Android 图片压缩

首先扯点别的:最近上海的天气也是热的不得了,早上跑步也不合适了,中午吃饭也没胃口。

今天记录一下Android中的图片压缩。注意,为了简单,代码中需要的读写存储空间的权限已经在上一个页面申请过了。

尺寸压缩

改变图片的尺寸,比如说原来是1280×1902的变成640×320的。压缩图片的尺寸可以减少图片占用的内存大小。

获取一个Bitmap占用内存大小的方法,可以使用Bitmap的getByteCount()方法。

    /**
     * Returns the minimum number of bytes that can be used to store this bitmap's pixels.
     */
    public final int getByteCount() {
        // int result permits bitmaps up to 46,340 x 46,340
        return getRowBytes() * getHeight();
    }

举个例子:从drawable目录下加载一张图片到ImageView上,对比不使用尺寸压缩和使用尺寸压缩后,bitmap所占用的内存。(ImageView的宽为200dp,高为140dp)

这里写图片描述

先把上面的图片放到drawable-xxhdpi目录下。

不使用尺寸压缩

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_compress);
        ButterKnife.bind(this);
        Bitmap bitmap = ImageUtil.getBitmapFromResource(getResources(), R.drawable.airplane);
        Log.e(TAG, "bitmap占用的内存" + bitmap.getByteCount()/1024/1024 + "MB");
        imgLarge.setImageBitmap(bitmap);
    }
 public static Bitmap getBitmapFromResource(Resources res, int resId) {
        return BitmapFactory.decodeResource(res, resId);
    }

占用的内存

CompressActivity: bitmap占用的内存8MB

使用尺寸压缩

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_compress);
        ButterKnife.bind(this);
        //把dp转化成px
        width = ScreenUtil.dipToPx(this, 200);
        height = ScreenUtil.dipToPx(this, 140);
        Bitmap bitmap = ImageUtil.getSampledBitmapFromResource(getResources(), R.drawable.airplane, width, height);
        Log.e(TAG, "bitmap占用的内存" + bitmap.getByteCount()/1024/1024 + "MB");
        imgLarge.setImageBitmap(bitmap);
    }
 public static Bitmap getSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }
  /**
     * @param options   options
     * @param reqWidth  目标宽度
     * @param reqHeight 目标高度
     * @return inSampleSize 指示了在解析图片为Bitmap时在长宽两个方向上像素缩小的倍数
     */
    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            // Calculate the largest inSampleSize value that is a power of 2 and keeps both height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) >= reqHeight
                    && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

使用尺寸压缩后,占用的内存

CompressActivity: bitmap占用的内存2MB

可以看到根据ImageView的大小来对要加载的图片进行尺寸压缩,可以明显减少图片占用内存的大小。

质量压缩

改变图片所占的存储空间的大小,比如把一个3M的图片压缩到400KB。
当我们在浏览一些新闻,想要把图片保存到手机上的时候,就应该使用质量压缩。
这里写图片描述

把这个ImageView(尺寸200dp×140dp)上的图片保存到本地。

  /**
     * 把imageView上的bitmap保存到本地,直接在主线程保存
     */
    @OnClick(R.id.btn_save_bitmap)
    public void saveBitmap() {
        String destination = null;
        imgLarge.setDrawingCacheEnabled(true);
        Bitmap bitmap = imgLarge.getDrawingCache();
        if (bitmap != null) {
            try {
                destination = ImageUtil.compressImage(CompressActivity.this, bitmap, 70);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (TextUtils.isEmpty(destination)) {
                Toast.makeText(CompressActivity.this, "保存失败", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(CompressActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
            }
        }
        imgLarge.setDrawingCacheEnabled(false);
    }
 /**
     * @param context  上下文对象
     * @param bitmap   要存在
     * @param quantity 压缩质量
     * @return 存储的压缩后的路径
     * @throws FileNotFoundException
     */
    public static String compressImage(Context context, Bitmap bitmap, int quantity) throws IOException {
        File imageFile = createImageFile();
        FileOutputStream out = new FileOutputStream(imageFile);
        bitmap.compress(Bitmap.CompressFormat.JPEG, quantity, out);
        out.flush();
        out.close();
        //通知媒体扫描器扫描文件
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri contentUri = Uri.fromFile(imageFile);
            mediaScanIntent.setData(contentUri);
            context.sendBroadcast(mediaScanIntent);
        } else {
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + imageFile.getAbsoluteFile())));
        }
        return imageFile.getPath();
    }
   /**
     * 创建图片File对象
     *
     * @return
     */
    public static File createImageFile() {
        File imageFile = null;
        String storagePath;
        File storageDir;
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        try {
            storagePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + File.separator + "camerademo";
            storageDir = new File(storagePath);
            storageDir.mkdirs();
            imageFile = File.createTempFile(timeStamp, ".jpg", storageDir);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageFile;
    }

这个图片原来的大小是290KB,尺寸是1920×1200。采用质量压缩后的大小是52KB,尺寸是600×420,压缩效果还是不错的。而且图片也没失真。

总结:当我们要把图片加载到内存中,应该使用尺寸压缩。当我们要把图片保存的本地,应该使用质量压缩。质量压缩并不能减少图片所占用的内存。如果我们要把图片传输到网络上,可以先把图片进行尺寸压缩加载到应用中,然后把加载进来的图片再进行质量压缩,然后再保存到手机中。我们传输这个压缩后的图片即可。(省流量)

参考链接

【1】http://blog.csdn.net/love_techlive/article/details/52024844

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值