图片选择功能基本都有吧 坑也很多记录一下。
android 打开照相机
String outFileFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath();
String outFilePath = getNowDateTime("yyyyMMdd_HHmmssSSS") + ".jpg";
File file = new File(outFileFolder, outFilePath);
mCameraFilePath = file.getAbsolutePath();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
uri = Uri.fromFile(file); //有的手机得不到照相的路径,只能把相片保存到自定义的文件夹下面。
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, TOKE_PIC);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Log.e("ljl", "获取相片的路径==" + mCameraFilePath + "-----" + mCameraFilePath.getBytes().toString());
Bitmap bmp = BitmapFactory.decodeFile(mCameraFilePath);
Log.e("ljl", "bmp" + bmp.getWidth() + "----bmp----" + bmp.getHeight());
// 获取屏幕分辨率
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
// 图片分辨率与屏幕分辨率
float scale_2 = bmp.getWidth() / (float) dm.widthPixels;
//显示图片的时候必须要对图片进行出来要不然图片不显示
Bitmap newBitMap_2 = null;
if (scale_2 > 1) {
newBitMap_2 = zoomBitmap(bmp, bmp.getWidth()
/ scale_2, bmp.getHeight() / scale_2);
bmp.recycle();
isBig = true;
imageView.setImageBitmap(newBitMap_2);
} else {
imageView.setImageBitmap(bmp);
}
}
}
// 对分辨率较大的图片进行缩放
public Bitmap zoomBitmap(Bitmap bitmap, float width, float height) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidth = ((float) width / w);
float scaleHeight = ((float) height / h);
matrix.postScale(scaleWidth, scaleHeight);// 利用矩阵进行缩放不会造成内存溢出
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
return newbmp;
}
三、计算机解析图片的方式和Android中大图片Bitmap的压缩显示处理
这个问题有点老生长谈了,平时我们经常遇到一些图片资源,我们把它加载到内存发现抛出内存不够用的异常,即OOM,当然加载图片时出现的OOM情况有很多种,比如单张图片没有做压缩,导致图片占用内存过大而发生内存溢出,也有多张图片一次性加载进来,导致的内存溢出。
通常单张大图,我们加载进来往往会经过一个图片的压缩处理的过程,而如果多张图片加载,我们可能就需要一些缓存机制,再加上一些算法来保证程序不出现OOM。
我们这里想要讲的知识点跟单张大图比较有关系
首先,我们知道一个图片,它是由很多像素点来表示的,而像素点的个数只跟图片的分辨率有关,而跟图片所占的内存空间大小无关。比如我们的桌面壁纸:1280 * 768 的分辨率,那么它就有 1280 * 768 = 983040个像素点,这意味着什么呢?我们知道我们要表示一个像素点的颜色,最经常我们需要RGB三种颜色来表示,而R:0~255,相当于两个FF的位置,就是8位,这样的话RGB合起来,一个像素点的表示就需要24位(这就是我们平衡听到的24位图),而加上透明度的8位,就是平时说的32位图。那么一张图片,它加载到内存中的话,它会占用多大的空间呢?
计算方法:(像素点 * 一个像素所占用的byte数) / 1024 / 1024 (MB)
以1280 * 768 的分辨率,32位图为例:所占内存大小: ((1280 * 768 * (32 / 8)) / 1024)/1024=3.75(MB)
图片压缩
public static Bitmap getScaleBitmap(Context ctx, String filePath) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, opt);
int bmpWidth = opt.outWidth;
int bmpHeght = opt.outHeight;
WindowManager windowManager = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
opt.inSampleSize = 1;
if (bmpWidth > bmpHeght) {
if (bmpWidth > screenWidth)
opt.inSampleSize = bmpWidth / screenWidth;
} else {
if (bmpHeght > screenHeight)
opt.inSampleSize = bmpHeght / screenHeight;
}
opt.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(filePath, opt);
Log.e("ljl", "新的bitmap的宽=" + bmp.getWidth() + "--新的bitmap的高=" + bmp.getHeight());
return bmp;
}
在介绍之前先说下一个概念性问题:
一、URI
通用资源标志符(Universal Resource Identifier, 简称”URI”)。
Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。
URI一般由三部分组成:
访问资源的命名机制。
存放资源的主机名。
资源自身的名称,由路径表示。
Android的Uri由以下三部分组成: “content://”、数据的路径、标示ID(可选)
举些例子,如:
所有联系人的Uri: content://contacts/people
某个联系人的Uri: content://contacts/people/5
所有图片Uri: content://media/external
某个图片的Uri:content://media/external/images/media/4
打开相册
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.addCategory(Intent.CATEGORY_OPENABLE);
galleryIntent.setType("image/*");//图片
startActivityForResult(galleryIntent, IMAGE_CODE); //跳转,传递打开相册请求码
if (requestCode == IMAGE_CODE) {//相册数据
Log.e("ljl", "获取图片的uri=" + data.getData());
Uri p_uro = data.getData();
Log.e("ljl", "获取图片路径==" + getRealPathFromURI(p_uro));
if (p_uro != null) {
//去裁剪
resizeImage(data.getData());
//imageView.setImageBitmap(getScaleBitmap(this, getRealPathFromURI(p_uro)));
}
//重塑图片大小
public void resizeImage(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// crop为true是设置在开启的intent中设置显示的view可以剪裁
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX,outputY 是剪裁图片的宽高
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
intent.putExtra("noFaceDetection", true);
startActivityForResult(intent, RESIZE_CODE);//跳转,传递调整大小请求码
}
处理裁剪的结果
if (requestCode == RESIZE_CODE) { // 裁剪得到的数据
Log.e("ljl", "裁剪以后获取图片的uri=" + data.getData());
// Uri p_uro = data.getData();
// if (p_uro != null) {
// imageView.setImageBitmap(getScaleBitmap(this, getRealPathFromURI(p_uro)));
// }
Log.e("ljl", "裁剪=====" + data);
if (data != null) {
// 剪裁图片并保存
Bundle bundle = data.getExtras();
if (bundle != null) {
photo = bundle.getParcelable("data");
} else {
try {
photo = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
Log.e("ljl", "裁剪的bitmap" + photo.getWidth() + "-------------" + photo.getHeight());
imageView.setImageBitmap(photo);
}
}
基本的功能就差不多了,以后有发现问题在记录。