Android 图片压缩

来源:互联网 发布:mac版千牛多账号登陆 编辑:程序博客网 时间:2024/06/05 10:48

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

今天记录一下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

原创粉丝点击