android图片压缩工具类

   好久没写博客了,一方面是因为最近找了家实习单位,很累基本上下班后就没有打不起精神去学习,另一方面我自己觉得写博客确实有点耗时间,趁着周六周日想花点时间研究下fresco,picass,Glide等框架,但是如何哪种框架,Bitmap总是基础,花了一上午的时间整理了下bitmap压缩的工具类,这里分享一下

 

package com.example.liujian.bitmapdemo;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.util.Log;
import android.view.WindowManager;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * create by liujian 2015/11/10
 * 图片压缩工具类
 */
public class ImageResizerUtils {
    private static final String TAG = ImageResizerUtils.class.getSimpleName();
    private Context context;
    private WindowManager mWindowManager;
    public ImageResizerUtils(Context context) {
       this.context=context;
    }
    
    /**
     * 放大缩小图片,指定宽高
     * @param bitmap
     * @param w
     * @param h
     * @return
     */
    public  Bitmap resizeBitmap(Bitmap bitmap, int w, int h) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidht = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidht, scaleHeight);
        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
                matrix, true);
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
        }
        return newbmp;
    }


    /**
     * Matrix类实现图片放大缩小,指定宽,宽高比例跟原图一致
     * @param bitmap 
     * @param newWidth 
     * @return 
     */  
    public  Bitmap resizeBitmap(Bitmap bitmap, int newWidth) {
        if (bitmap == null)  
            return null;  
        int w = bitmap.getWidth();  
        int h = bitmap.getHeight();  
                
        float temp = ((float) h) / ((float) w);  
        int newHeight = (int) (newWidth * temp);  
        float scaleWidth = ((float) newWidth) / w;  
        float scaleHeight = ((float) newHeight) / h;  
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix,  
                true);  
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
        }
        return resizedBitmap;  
    }


    /**
     * 压缩成屏幕能够接受的大小
     * @param is
     * @return
     */
    public Bitmap resizeBitmap(FileInputStream is) throws IOException {
        return resizeBitmap(is.getFD());
    }

    public Bitmap resizeBitmap(FileInputStream is,int reqWidth,int reqHeight) throws IOException {
        return resizeBitmap(is.getFD(),reqWidth,reqHeight);
    }

    public Bitmap resizeBitmap(FileDescriptor fd) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFileDescriptor(fd, null, options);
        options.inSampleSize = calculateInWindowSize(options);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFileDescriptor(fd, null, options);
    }


    /**
     * 压缩方法对FileInputStream的缩放存在问题,原因是FileInputStream是一种有序的
     * 文件流,而两次decodeStream调用影响了文件流的位置属性,导致第二次BitmapFactory.
     * decodeStream时得到是null。我们可以通过文件流来得到它所对应的文件描述符,
     * @param fd:FileDescriptor df = is.getFD();
     * @param reqWidth:所需图片宽(像素)
     * @param reqHeight:所需图片高(像素)
     * @return
     */
    public Bitmap resizeBitmap(FileDescriptor fd,int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFileDescriptor(fd, null, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);

        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFileDescriptor(fd, null, options);
    }



    /**
     *
     * @param res:Resources对象
     * @param resId:资源文件id
     * @return
     */
    public Bitmap resizeBitmap(Resources res, int resId) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 不去解析真正的位图,只是去获取这个文件的头文件信息
        BitmapFactory.decodeResource(res, resId, options);

        // 得到压缩的缩放比
        options.inSampleSize = calculateInWindowSize(options);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }


    /**
     *
     * @param res:Resources对象
     * @param resId:资源文件id
     * @param reqWidth:缩放的目标Bitmao的宽度
     * @param reqHeight:缩放的目标Bitmap的高度
     * @return
     */
    public Bitmap resizeBitmap(Resources res, int resId,
                                                  int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 不去解析真正的位图,只是去获取这个文件的头文件信息
        BitmapFactory.decodeResource(res, resId, options);

        // 得到压缩的缩放比
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);

        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }



    /**
     * 根据路径压缩成指定的宽高
     * @param path
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public Bitmap resizeBitmap(String path,int reqWidth,int reqHeight){
        BitmapFactory.Options opts=new BitmapFactory.Options();//解析位图的附加条件
        opts.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(path,opts);

        opts.inSampleSize=calculateInSampleSize(opts,reqWidth,reqHeight);
        opts.inJustDecodeBounds=false;
        return BitmapFactory.decodeFile(path,opts);
    }

    /**
     * 根据路径压缩成屏幕可以接受的大小
     * @param path
     * @return
     */
    public Bitmap resizeBitmap(String path){
        BitmapFactory.Options opts=new BitmapFactory.Options();//解析位图的附加条件
        opts.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(path,opts);

        opts.inSampleSize=calculateInWindowSize(opts);
        opts.inJustDecodeBounds=false;
        return BitmapFactory.decodeFile(path,opts);
    }

    /**
     * 根据需要的图片宽高(px像素)来压缩 返回缩放比 缩放比大于1时,比如为2,
     * 压缩后的图片其宽高均为原图大小的1/2,其所占的内存大小也为原图的1/4
     * @param options
     * @param reqWidth:压缩的目标宽
     * @param reqHeight:压缩的目标高
     * @return 返回缩放比
     */
    private int calculateInSampleSize(BitmapFactory.Options options,
                                     int reqWidth, int reqHeight) {
        if (reqWidth <= 0 || reqHeight <= 0) {
            return 1;
        }
        // 得到图片的宽高
        final int height = options.outHeight;
        final int width = options.outWidth;
        Log.d(TAG, "origin, w= " + width + " h=" + height);
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            while ((halfHeight / inSampleSize) >= reqHeight
                    && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }
        Log.d(TAG, "sampleSize:" + inSampleSize);
        return inSampleSize;
    }


    /**
     * 压缩成屏幕能够接受的大小的缩放比
     * @param options
     * @return
     */
    private int calculateInWindowSize(BitmapFactory.Options options){
        //得到屏幕宽高
        if(mWindowManager==null){
            mWindowManager=((Activity)context).getWindowManager();
        }
        int windowWidth=mWindowManager.getDefaultDisplay().getWidth();
        int windowHeight=mWindowManager.getDefaultDisplay().getHeight();

        int bitmapWidth=options.outWidth;
        int bitmapHeight=options.outHeight;
        int dx=bitmapWidth/windowWidth;
        int dy=bitmapHeight/windowHeight;
        int scale=1;
        if(dx>dy&&dy>1){
           scale=dx;
        }
        if(dy>dx&&dy>1){
            scale=dy;
        }
        return scale;
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值