博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
选择相册、拍照,图片过大导致控件无法显示图片
阅读量:6335 次
发布时间:2019-06-22

本文共 7340 字,大约阅读时间需要 24 分钟。

hot3.png

拍照及选择照片略。

在onActivityResult方法里通过Intent的getData方法获取的数据转换成bitmap并显示在界面上,有时候会有取不到数据,或者显示的bitmap会非常小,如果将bitmap保存到sd卡后会发现,图片的分辨率很低,并且图片大小也是经过压缩的,不管将相机的像素设置多高,最后通过这种方式返回的bitmap总是经过压缩了的。如果想获得理想的照片大小和分辨率改如何处理呢?

另外官方文档中有说明,Android系统分配给每个应用的最大内存是16M,所以,系统为了防止应用内存占用过大,对于在应用内通过相机拍摄的图片最终返回来的结果进行了压缩,压缩后的图片变得很小,通过之前说的getData的方式只能满足比如显示个头像这样的需求。

拍照时,将拍得的照片先保存在本地,通过修改之前的代码如下:

Intent intent = new Intent(         "android.media.action.IMAGE_CAPTURE");imageUri = Uri.fromFile(new File(Environment          .getExternalStorageDirectory(),          "photo.jpg"));        // 指定照片保存路径(SD卡),photo.jpg为一个临时文件,每次拍照后这个图片都会被替换(未压缩)        intent.putExtra(MediaStore.EXTRA_OUTPUT,          imageUri);startActivityForResult(intent, CODE_TAKE_PHOTO);

在onActivityResult中:

if(requestCode == TAKE&& resultCode == RESULT_OK){       startPhotoZoom(imageUri);//进行图片的剪切操作 }

private void startPhotoZoom(Uri uri) {  try {   // 获取系统时间 然后将裁剪后的图片保存至指定的文件夹   SimpleDateFormat sDateFormat = new SimpleDateFormat(     "yyyyMMddhhmmss");   String address = sDateFormat.format(new java.util.Date());   if (!FileUtils.isFileExist("")) {    FileUtils.createSDDir("");   }   Log.d("TAG", "path = " + FileUtils.SDPATH + address + ".JPEG");   Uri imageUri = Uri.parse("file://" + FileUtils.SDPATH + address     + ".JPEG");   // 执行剪切得到正方形,图片的路径   path_original = FileUtils.SDPATH + address + ".JPEG";   final Intent intent = new Intent("com.android.camera.action.CROP");   // 照片URL地址   intent.setDataAndType(uri, "image/*");   intent.putExtra("crop", "true");   intent.putExtra("aspectX", 1);   intent.putExtra("aspectY", 1);   intent.putExtra("outputX", 480);   intent.putExtra("outputY", 480);   // 输出路径   intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);   // 输出格式   intent.putExtra("outputFormat",     Bitmap.CompressFormat.JPEG.toString());   // 不启用人脸识别   intent.putExtra("noFaceDetection", false);   intent.putExtra("return-data", false);   startActivityForResult(intent, CUT_PHOTO_REQUEST_CODE);  } catch (IOException e) {   e.printStackTrace();  } }

 剪切返回后在onActivityResult中进行压缩,然后显示到ImageView控件上。

为什么要压缩呢,因为即使是已经截图了的图片,也可能图片还是过大,控件无法显示图片内容。压缩之后的文件保存在path路径所在的文件中。

 if (requestCode == CUT_PHOTO_REQUEST_CODE    && resultCode == RESULT_OK) {    Bitmap smallBitmap = null;   try {    smallBitmap = BitmapUtil.revitionImageSize(path_original,                //压缩Bitmap得到smallBitmap      n_Bitmap_size_show);   } catch (IOException e1) {    // TODO Auto-generated catch block    e1.printStackTrace();   }    iv_storelogo.setImageBitmap(smallBitmap);    path = Environment.getExternalStorageDirectory() + "/photo.jpg";    File file = new File(path);    if (file.exists()) {        file.delete();    }    FileOutputStream fOut = null;    try {        fOut = new FileOutputStream(new File(path));    } catch (FileNotFoundException e1) {    // TODO Auto-generated catch block    e1.printStackTrace();   }       smallBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);// 把Bitmap对象解析成流,写到文件中}

 接下来我把BitmapUtil文件的源码贴出来,供大家参考。也就是压缩技术

public class BitmapUtil { private static final int STROKE_WIDTH = 4; /**  * 压缩图片到指定大小  *   * @param path  * @param size  *            图片的大小  * @return  * @throws IOException  */ public static Bitmap revitionImageSize(String path, int size)   throws IOException {  BufferedInputStream in = new BufferedInputStream(new FileInputStream(    new File(path)));  BitmapFactory.Options options = new BitmapFactory.Options();  options.inJustDecodeBounds = true;  // Bitmap btBitmap=BitmapFactory.decodeFile(path);  // System.out.println("原尺寸高度:"+btBitmap.getHeight());  // System.out.println("原尺寸宽度:"+btBitmap.getWidth());  BitmapFactory.decodeStream(in, null, options);  in.close();  int i = 0;  Bitmap bitmap = null;  while (true) {   // 这一步是根据要设置的大小,使宽和高都能满足   if ((options.outWidth >> i <= size)     && (options.outHeight >> i <= size)) {    // 重新取得流,注意:这里一定要再次加载,不能二次使用之前的流!    in = new BufferedInputStream(      new FileInputStream(new File(path)));    // 这个参数表示 新生成的图片为原始图片的几分之一。    options.inSampleSize = (int) Math.pow(2.0D, i);    // 这里之前设置为了true,所以要改为false,否则就创建不出图片    options.inJustDecodeBounds = false;    bitmap = BitmapFactory.decodeStream(in, null, options);    break;   }   i += 1;  }  // 当机型为三星时图片翻转  // bitmap = Photo.photoAdapter(path, bitmap);  // System.out.println("-----压缩后尺寸高度:" + bitmap.getHeight());  // System.out.println("-----压缩后尺寸宽度度:" + bitmap.getWidth());  return bitmap; }/**  * 根据文件名得到,Bitmap对象  * @param url 文件的路径全名  * @return  */ public static Bitmap getLoacalBitmap(String url) {  try {   FileInputStream fis = new FileInputStream(url);   return BitmapFactory.decodeStream(fis); // /把流转化为Bitmap图片  } catch (FileNotFoundException e) {   e.printStackTrace();   return null;  } }  /**  *   * @param x  *            图像的宽度  * @param y  *            图像的高度  * @param image  *            源图片  * @param outerRadiusRat  *            圆角的大小  * @return 圆角图片  */ public static Bitmap createFramedPhoto(int x, int y, Bitmap image,   float outerRadiusRat) {  // 根据源文件新建一个darwable对象  Drawable imageDrawable = new BitmapDrawable(image);  // 新建一个新的输出图片  Bitmap output = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);  Canvas canvas = new Canvas(output);  // 新建一个矩形  RectF outerRect = new RectF(0, 0, x, y);  // 产生一个红色的圆角矩形  Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);  paint.setColor(Color.RED);  canvas.drawRoundRect(outerRect, outerRadiusRat, outerRadiusRat, paint);  // 将源图片绘制到这个圆角矩形上  paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));  imageDrawable.setBounds(0, 0, x, y);  canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG);  imageDrawable.draw(canvas);  canvas.restore();  return output; } /**  * 生成圆角的Bitmap STROKE_WIDTH为白色圆圈的宽度  *   * @param context  * @param bitmap  * @return  */ public static Bitmap toRoundBitmap(Context context, Bitmap bitmap) {  int width = bitmap.getWidth();  int height = bitmap.getHeight();  float roundPx;  float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;  if (width <= height) {   roundPx = width / 2;   top = 0;   left = 0;   bottom = width;   right = width;   height = width;   dst_left = 0;   dst_top = 0;   dst_right = width;   dst_bottom = width;  } else {   roundPx = height / 2;   float clip = (width - height) / 2;   left = clip;   right = width - clip;   top = 0;   bottom = height;   width = height;   dst_left = 0;   dst_top = 0;   dst_right = height;   dst_bottom = height;  }  Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);  Canvas canvas = new Canvas(output);  final Paint paint = new Paint();  final Rect src = new Rect((int) left, (int) top, (int) right,    (int) bottom);  final Rect dst = new Rect((int) dst_left, (int) dst_top,    (int) dst_right, (int) dst_bottom);  final RectF rectF = new RectF(dst);  paint.setAntiAlias(true);  canvas.drawARGB(0, 0, 0, 0);  paint.setColor(Color.BLUE);  paint.setStrokeWidth(4);  canvas.drawRoundRect(rectF, roundPx, roundPx, paint);  paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  canvas.drawBitmap(bitmap, src, dst, paint);  // 画白色圆圈  paint.reset();  paint.setColor(Color.BLUE);  paint.setStyle(Paint.Style.STROKE);  paint.setStrokeWidth(STROKE_WIDTH);  paint.setAntiAlias(true);  canvas.drawCircle(width / 2, width / 2, width / 2 - STROKE_WIDTH / 2,    paint);  return output; }}

希望对大家有所帮助。如果大家有问题,或者更好的建议,欢迎大家留言。

转载于:https://my.oschina.net/u/660536/blog/368662

你可能感兴趣的文章
Distributed2:Linked Server Login 添加和删除
查看>>
Java中取两位小数
查看>>
使用 ftrace 调试 Linux 内核【转】
查看>>
唯一聚集索引上的唯一和非唯一非聚集索引
查看>>
Spark新愿景:让深度学习变得更加易于使用——见https://github.com/yahoo/TensorFlowOnSpark...
查看>>
linux磁盘配额
查看>>
NFS文件共享服务器的搭建
查看>>
%r 和 %s 该用哪个?
查看>>
小公司职场不是“切糕”
查看>>
play工程部署到云服务器
查看>>
ListView 取消点击效果
查看>>
wampServer连接oracle
查看>>
CentOS 6.5下编译安装新版LNMP
查看>>
Android Picasso
查看>>
top命令
查看>>
javascript的作用域
查看>>
新形势下初创B2B行业网站如何经营
查看>>
初心大陆-----python宝典 第五章之列表
查看>>
java基础学习2
查看>>
sysbench使用笔记
查看>>