Advertisement

Bitmap所遇到的坑

阅读量:

图片至关重要,则使得Bitmap变得至关重要。
然而,在实际应用中发现使用Bitmap可能会遇到一些问题。
对此进行了深入分析。

  • 如何完整地将Bitmap呈现于ImageView中
  • 如何保存一个Bitmap
  • 如何快速且高效地加载Bitmaps

如何将Bitmap在ImageView中完整的显示

这个功能可以在我的自定义组件中实现:按下按钮触发相机拍摄,并将获取的照片返回该Activity并呈现出来;我们已知通过on setResult()可以实现基本效果;但遗憾的是,在图像展示环节存在不足:无法按照原始尺寸展示照片

通过查阅资料得知,在手机拍摄的照片中通常具有较高的像素值;然而在直接展示时由于占用较多内存资源因此系统默认会对图片进行压缩处理这可能导致全屏展示的画面尺寸大幅缩小甚至难以察觉

下面是测试通过的代码和结果,可以做个参考:

复制代码
    public static Bitmap compressImage(Bitmap image)
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 2000)
        { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }
    
    public static void showImage(Context context, ImageView mImageView, Bitmap imageBitmap){
        //对Bitmap进行裁剪
        //imageBitmap = Bitmap.createBitmap(
        //        imageBitmap, 0, imageBitmap.getHeight()/4, imageBitmap.getWidth(), imageBitmap.getWidth() / 2);
        //float scaleHeigth = getApplicationContext().getResources().getDisplayMetrics().heightPixels * 0.8f;
        //show in original size of bitmap
        float scaleWidth = context.getApplicationContext().getResources().getDisplayMetrics().widthPixels;
        float height = imageBitmap.getHeight();
        float width = imageBitmap.getWidth();
        int scale = (int) (scaleWidth / width);
        mImageView.setLayoutParams(new LinearLayout.LayoutParams((int)(scale * width) , (int)(scale * height)));
        mImageView.setScaleType(ImageView.ScaleType.FIT_XY);
        //imageBitmap = Bitmap.createScaledBitmap(imageBitmap,imageBitmap.getWidth(), imageBitmap.getHeight(), true);
        //按长宽比2 : 1对Bitmap进行裁剪
        //imageBitmap = Bitmap.createBitmap(imageBitmap, 0, imageBitmap.getHeight()/4, imageBitmap.getWidth(), imageBitmap.getWidth() / 2);
        mImageView.setImageBitmap(imageBitmap);
        mImageView.setVisibility(View.VISIBLE);
    }
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解释
这里写图片描述

如何存储一个Bitmap

请看这篇博客,代码简短实用!

复制代码
    public static void storeImage(Context context, String name, Bitmap image) {
        File pictureFile = getOutputMediaFile(context, name);
        if (pictureFile == null) {
            Toast.makeText(context, "Fail to create a image file3", Toast.LENGTH_SHORT).show();
            Log.d(TAG,
                    "Error creating media file, check storage permissions: ");// e.getMessage());
            return;
        }
        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            image.compress(Bitmap.CompressFormat.PNG, 90, fos);
            fos.close();
        } catch (FileNotFoundException e) {
            Toast.makeText(context, "Fail to create a image file4", Toast.LENGTH_SHORT).show();
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Toast.makeText(context, "Fail to create a image file5", Toast.LENGTH_SHORT).show();
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
    
    public static File getOutputMediaFile(Context context, String name){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.
        File mediaStorageDir = new File(context.getFilesDir(), "Navigation");
    
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.
    
        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            Toast.makeText(context, "Fail to create a image file1", Toast.LENGTH_SHORT).show();
            if (! mediaStorageDir.mkdirs()){
                Toast.makeText(context, "Fail to create a image file2", Toast.LENGTH_SHORT).show();
                return null;
            }
        }
        File mediaFile;
        String mImageName= name +".jpg";
        mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
        return mediaFile;
    }
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解释

如何高效加载Bitmap

这个我就不废话了,直接看视频吧,老师讲的很好。

阐述了在ListView中高效加载图片的方法,并利用缓存机制以避免多次加载同一图片的情况。该方法具有较高的效率和稳定性。教师对此予以高度赞赏并给予充分肯定

全部评论 (0)

还没有任何评论哟~