图片压缩最保真方法

可以支持按比例裁剪和缩放图片,限制生成的图片大小,最多3次缩放就可以达到想要的图片。

代码:
    /**
     * @param bitmap   原图
     * @param wh       宽高比 例:5:4 就是0.8
     * @param maxBytes 最大字节数 例:小程序限制128k maxBytes就是1028*128
     */
    public static byte[] creatBitmapByWidth(Bitmap bitmap, float wh, int maxBytes) {

        //裁剪
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Bitmap myBitmap = null;
        if (wh > 0) {
            myBitmap = Bitmap.createBitmap(bitmap, 0, 0, w, (int) (((float) w) * wh));
            bitmap.recycle();
        } else {
            myBitmap = bitmap;
        }

        //缩放
        byte[] myBytes = null;
        Bitmap newBitmap = null;
        float defaulSacle = 0f;

        myBytes = ShareUtil.bmpToByteArray(myBitmap, 75);
        //最大限制数和压缩后bitmap大小的比值,开方取到最接近的缩放值,乘以0.9有一定几率减少下面的缩放次数。
        defaulSacle = (float) Math.sqrt((double) maxBytes / (double) myBytes.length) * 0.9f;

        while (myBytes.length >= maxBytes) {//每次缩放10%
            Matrix matrixwhile = new Matrix();
            matrixwhile.preScale(defaulSacle, defaulSacle);
            newBitmap = Bitmap.createBitmap(myBitmap, 0, 0, w, h, matrixwhile, false);
            myBytes = ShareUtil.bmpToByteArray(newBitmap, 75);
            newBitmap.recycle();

            //继续计算缩放值,每循环一次,就更接近最大限制,也就更精确。
            double newSacle = (float) Math.sqrt((double) maxBytes / (double) myBytes.length) * 0.9f;
            if (newSacle > 0.9) {//防止死循环,因为newSacle会无限制接近1,
                newSacle = 0.9;
            }
            defaulSacle = defaulSacle * (float) newSacle;
        }
        myBitmap.recycle();
        return myBytes;
    }
    public static byte[] bmpToByteArray(Bitmap bitmap,int quality) {
        if (bitmap == null) {
            return null;
        }
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, output);
        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
原文地址:https://www.cnblogs.com/wangyuehome/p/7255750.html