Android 图片裁剪 超出内存
2015-06-23 20:51
751 查看
刚进项目组,调试头像上传功能,选取图片后裁剪图片时就出问题了,用同事的手机调都可以,我的华为 honor6 不行,桑心!
然后各种翻资料,看博客,几乎写的都一个样,规整规整也就拼出了解决办法。我的手机裁剪时直接异常挂掉,其实是因为图片太大,剪切后内存超了,所以采用的另一种办
法。这里先引用张参数图。
再加入源码
这里在裁剪玩了图片之后,有不同的处理方法
一、在startPhotoZoom方法中return-data设置为true,就会返回一个BitMap对象,这样outputX和outputY设置大了很可能会超出内存(这里貌似会牵扯到默认存储的颜色模式),所以这种方法不可取
二、还有种就是把return-data设置为false,把裁剪后的图片存到一个目录,记录其Uri,然后去读取。
然后各种翻资料,看博客,几乎写的都一个样,规整规整也就拼出了解决办法。我的手机裁剪时直接异常挂掉,其实是因为图片太大,剪切后内存超了,所以采用的另一种办
法。这里先引用张参数图。
再加入源码
public class MyPicActivity extends Activity implements OnClickListener{ private ImageView img = null; private Button btn = null; private File cache, file; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_pic); img = (ImageView) findViewById(R.id.img); btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(this); cache = new File(Environment.getExternalStorageDirectory(), "ZSYSPIC"); if (!cache.exists()) { cache.mkdirs(); } file = new File(cache, "temp.jpg"); } @Override public void onClick(View v) { Intent intent1 = new Intent(Intent.ACTION_PICK, null); intent1.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent1.setType("image/*"); startActivityForResult(intent1, 1); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case 1: if (data != null) { Uri originalUri = data.getData(); // 获得图片的uri String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(originalUri, proj, null, null, null); // 获得用户选择的图片的索引值 int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); // 将光标移至开头 ,这个很重要,不小心很容易引起越界 cursor.moveToFirst(); // 最后根据索引值获取图片路径 //String path = cursor.getString(column_index); //path = System.currentTimeMillis() + path.substring(path.lastIndexOf(".")); startPhotoZoom(originalUri); } break; case 2: //Bitmap bmap = data.getParcelableExtra("data"); //img.setImageBitmap(bmap); picture(file.getPath(), img); break; default: break; } } private void startPhotoZoom(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", 500); intent.putExtra("outputY", 500); intent.putExtra("scale", true); intent.putExtra("return-data", false); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(intent, 2); } public static void picture(String path, ImageView iView) { BitmapFactory.Options op = new Options(); op.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, op); int height = op.outHeight; int width = op.outWidth; int fit_X = width / 210; int fit_y = height / 150; int fit_XY = 1; if (fit_X > fit_y && fit_y >= 1) { fit_XY = fit_X; } if (fit_y > fit_X && fit_X >= 1) { fit_XY = fit_y; } op.inJustDecodeBounds = false; op.inSampleSize = fit_XY; Bitmap bm = BitmapFactory.decodeFile(path, op); iView.setImageBitmap(bm); } }
这里在裁剪玩了图片之后,有不同的处理方法
一、在startPhotoZoom方法中return-data设置为true,就会返回一个BitMap对象,这样outputX和outputY设置大了很可能会超出内存(这里貌似会牵扯到默认存储的颜色模式),所以这种方法不可取
Intent intent = new Intent("com.android.camera.action.CROP"); intent.setType("image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 2); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 200); intent.putExtra("outputY", 100); intent.putExtra("scale", true); intent.putExtra("return-data", true); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); startActivityForResult(intent, 1);在onActivityResult回执时
Bitmap bitmap = data.getParcelableExtra("data"); imageView.setImageBitmap(bitmap);但依然是那个问题,这里都是把裁剪后的图片缓存在内存中,图片大了就不行了。理想的处理方法见下面:
二、还有种就是把return-data设置为false,把裁剪后的图片存到一个目录,记录其Uri,然后去读取。
Intent intent = new Intent("com.android.camera.action.CROP"); intent.setType("image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 2); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 200); intent.putExtra("outputY", 100); intent.putExtra("scale", true); intent.putExtra("return-data", false); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", false); startActivityForResult(intent, 1);在onActivityResult回执时
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)); imageView.setImageBitmap(bitmap);大功告成,希望对大家有帮助,又不对之处望指出!
相关文章推荐
- Android实战简易教程-第二十枪(GridView长按显示删除)
- android 伸缩控件ExpandableListView 展开失败的可能原因。
- android布局之 GridLayout的使用
- Activity的七大生命周期
- android-textview
- 通过Intent传输图片导致广播消息异常的问题根因分析(通过分析Android源码反向推理)
- Android 通知栏ANR原因
- Android入门之GridView(九宫图)
- android-RecyclerView
- Android深入浅出之Zygote
- Android CTS(兼容性测试)整个流程
- android:android Intent and IntentFilter
- Ubuntu14.04下搭建android5.1编译环境
- Android内核开发:系统启动速度优化
- Android的事件分发(二)
- Java(Android) Excpetion
- android横竖屏切换的生命周期的问题
- android去标题栏,导航栏,状态栏(全屏显示)(6.23)
- Android studio使用git提交但是没有push,如何回退并保存
- Android学习 13 -> 图片资源ImageView