美文网首页Android
写个简单的异步图片压缩保存的类

写个简单的异步图片压缩保存的类

作者: 景山道人 | 来源:发表于2019-07-29 21:02 被阅读0次

思路:AsyncTask + inSampleSize + bitmap.compress
由于inSampleSize缩的都是2的倍数,所以有时候可能会压过头,不追求精度的话还是可以用着玩玩的,以及我没测过oom的情况,只是假设会有做了处理,效果如何并不可知……

话说构造的参数不该加m是吧……我懒得改了,就这样子吧(

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class ImageCropTask extends AsyncTask<Void, Void, Boolean> {

    private String mOriPath;
    private String mDesPath;
    private int mQuality;
    private int mMaxHeight;
    private int mMaxWidth;
    private int mMaxSize;
    private ImageCropListener mCropListener;

    public ImageCropTask(String mOriPath, String mDesPath) {
        this(mOriPath, mDesPath, 90, -1, -1, -1, null);
    }

    /**
     * 递归压缩大小或者宽高,直到符合规定的大小
     *
     * @param mOriPath 原路径
     * @param mDesPath 目的地路径
     * @param mQuality 图片转换质量
     * @param mMaxHeight 最大高度
     * @param mMaxWidth 最大宽度
     * @param mMaxSize 最大大小,单位是MB
     * @param mCropListener 监听
     */
    public ImageCropTask(String mOriPath, String mDesPath, int mQuality, int mMaxHeight, int mMaxWidth, int mMaxSize, ImageCropListener mCropListener) {
        this.mOriPath = mOriPath;
        this.mDesPath = mDesPath;
        this.mQuality = mQuality;
        this.mMaxHeight = mMaxHeight;
        this.mMaxWidth = mMaxWidth;
        this.mMaxSize = mMaxSize;
        this.mCropListener = mCropListener;
    }

    @Override
    protected Boolean doInBackground(Void... voids) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mOriPath, options);
        int heightSize = cropHeight(options.outHeight);
        int widthSize = cropWidth(options.outWidth);
        int sampleSize;
        if (heightSize > 0 || widthSize > 0) {
            sampleSize = Math.max(widthSize, heightSize);
            options.inSampleSize = sampleSize;
        }
        options.inJustDecodeBounds = false;
        Bitmap compressBitmap = decodeBitmap(options);
        return saveBitmap(compressBitmap) && cropSize(options);
    }

    @Override
    protected void onPostExecute(Boolean success) {
        if (null != mCropListener) {
            if (!success) {
                mCropListener.onCropFailed();
            } else {
                mCropListener.onCropSuccess();
            }
        }
    }

    private boolean cropSize(BitmapFactory.Options options) {
        if (mMaxSize < 0) {
            return true;
        }
        long maxSize = mMaxSize * 1024 * 1024;
        File f = new File(mDesPath);
        if (!f.exists()) {
            return false;
        }
        if (0 == options.inSampleSize) {
            options.inSampleSize = 1;
        }
        long length = f.length();
        if (length > maxSize) {
            options.inSampleSize *= 2;
            Bitmap newBitmap = decodeBitmap(options);
            return saveBitmap(newBitmap) && cropSize(options);
        }
        return true;
    }

    private boolean saveBitmap(Bitmap bitmap) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(mDesPath);
            return bitmap.compress(Bitmap.CompressFormat.JPEG, mQuality, out);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private Bitmap decodeBitmap(BitmapFactory.Options options) {
        Bitmap compressBitmap;
        try {
            compressBitmap = BitmapFactory.decodeFile(mOriPath, options);
        } catch (OutOfMemoryError e) {
            if (0 == options.inSampleSize) {
                options.inSampleSize = 1;
            }
            options.inSampleSize *= 2;
            compressBitmap = decodeBitmap(options);
        }
        return compressBitmap;
    }

    private int cropHeight(int outHeight) {
        if (mMaxHeight < 0) {
            return -1;
        }
        int multi = 1;
        int currHeight = outHeight;
        while (currHeight > mMaxHeight) {
            currHeight /= 2;
            multi *= 2;
        }
        return multi;
    }

    private int cropWidth(int outWidth) {
        if (mMaxWidth < 0) {
            return -1;
        }
        int multi = 1;
        int currWidth = outWidth;
        while (currWidth > mMaxWidth) {
            currWidth /= 2;
            multi *= 2;
        }
        return multi;
    }

    public ImageCropTask quality(int quality) {
        this.mQuality = quality;
        return this;
    }

    public ImageCropTask maxHeight(int maxHeight) {
        this.mMaxHeight = maxHeight;
        return this;
    }

    public ImageCropTask maxWidth(int maxWidth) {
        this.mMaxWidth = maxWidth;
        return this;
    }

    public ImageCropTask maxSize(int maxSize) {
        this.mMaxSize = maxSize;
        return this;
    }

    public ImageCropTask cropListener(ImageCropListener cropListener) {
        this.mCropListener = cropListener;
        return this;
    }
}

监听,如果有需要返回的参数可以自定义修改加上

public interface ImageCropListener {
    void onCropSuccess();
    void onCropFailed();
}

相关文章

网友评论

    本文标题:写个简单的异步图片压缩保存的类

    本文链接:https://www.haomeiwen.com/subject/ymiirctx.html