图片压缩最优方案

图片压缩最优方案

大家好,又见面了,我是全栈君。

Github地址: https://github.com/jeanboydev/Android-BitherCompress

原文地址:http://blog.csdn.net/copy_yuan/article/details/51353629

拓展:鲁班压缩 Github地址:https://github.com/Curzibn/Luban

源码(增加回调)

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Rect;

import java.io.ByteArrayOutputStream;

public class NativeUtil {
    private static int DEFAULT_QUALITY = 95;

    /**
     * @param bit      bitmap对象
     * @param fileName 指定保存目录名
     * @param optimize 是否采用哈弗曼表数据计算 品质相差5-10倍
     * @Description: JNI基本压缩
     */
    public static void compressBitmap(Bitmap bit, String fileName, boolean optimize) {
        saveBitmap(bit, DEFAULT_QUALITY, fileName, optimize);
    }

    public interface CompressBitmapListener {
        void onComplete(String fileUri);
    }

    /**
     * @param image bitmap对象
     * @Description: 通过JNI图片压缩把Bitmap保存到指定目录
     */
    public static void compressBitmap(Bitmap image, String filePath, CompressBitmapListener listener) {
        // 最大图片大小 1000KB
        int maxSize = 1000;
        // 获取尺寸压缩倍数
        int ratio = NativeUtil.getRatioSize(image.getWidth(), image.getHeight());
        // 压缩Bitmap到对应尺寸
        Bitmap result = Bitmap.createBitmap(image.getWidth() / ratio, image.getHeight() / ratio, Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Rect rect = new Rect(0, 0, image.getWidth() / ratio, image.getHeight() / ratio);
        canvas.drawBitmap(image, null, rect, null);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        result.compress(Bitmap.CompressFormat.JPEG, options, baos);
        // 循环判断如果压缩后图片是否大于最大值,大于继续压缩
        while (baos.toByteArray().length / 1024 > maxSize) {
            // 重置baos即清空baos
            baos.reset();
            // 每次都减少10
            options -= 10;
            // 这里压缩options%,把压缩后的数据存放到baos中
            result.compress(Bitmap.CompressFormat.JPEG, options, baos);
        }
        // JNI调用保存图片到SD卡 这个关键
        NativeUtil.saveBitmap(result, options, filePath, true);
        // 释放Bitmap
        if (result != null && !result.isRecycled()) {
            result.recycle();
            result = null;
        }
        listener.onComplete(filePath);
    }

    /**
     * 计算缩放比
     *
     * @param bitWidth  当前图片宽度
     * @param bitHeight 当前图片高度
     * @return
     * @Description:函数描述
     */
    public static int getRatioSize(int bitWidth, int bitHeight) {
        // 图片最大分辨率
        int imageHeight = 1920;
        int imageWidth = 1080;
        // 缩放比
        int ratio = 1;
        // 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        if (bitWidth > bitHeight && bitWidth > imageWidth) {
            // 如果图片宽度比高度大,以宽度为基准
            ratio = bitWidth / imageWidth;
        } else if (bitWidth < bitHeight && bitHeight > imageHeight) {
            // 如果图片高度比宽度大,以高度为基准
            ratio = bitHeight / imageHeight;
        }
        // 最小比率为1
        if (ratio <= 0)
            ratio = 1;
        return ratio;
    }

    /**
     * 调用native方法
     *
     * @param bit
     * @param quality
     * @param fileName
     * @param optimize
     * @Description:函数描述
     */
    private static void saveBitmap(Bitmap bit, int quality, String fileName, boolean optimize) {
        compressBitmap(bit, bit.getWidth(), bit.getHeight(), quality, fileName.getBytes(), optimize);
    }

    /**
     * 调用底层 bitherlibjni.c中的方法
     *
     * @param bit
     * @param w
     * @param h
     * @param quality
     * @param fileNameBytes
     * @param optimize
     * @return
     * @Description:函数描述
     */
    private static native String compressBitmap(Bitmap bit, int w, int h, int quality, byte[] fileNameBytes,
                                                boolean optimize);

    /**
     * 加载lib下两个so文件
     */
    static {
        System.loadLibrary("jpegbither");
        System.loadLibrary("bitherjni");
    }
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108622.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 升降压电路的工作原理

    升降压电路的工作原理1.升压电路也叫自举电路,是利用自举升压二极管,自举升压电容等电子元件,使电容放电电压和电源电压叠加,从而使电压升高,有的电路升高的电压能达到数倍电源电压。开关直流升压电路(即所谓的boost或者step-up电路)原理,theboostconverter,或者叫step-upconverter,是一种开关直流升压电路,它可以是输出电压比输入电压高。基本电路图如图所示假定那个开关(三极管或者mos管)已经断开了很长时间,所有的元件都处于理想状态,电容电压等于输入电压。下面要分充电和放电两个部分来

    2022年6月20日
    63
  • 高性能内存池_内存池化

    高性能内存池_内存池化文章目录项目简介内存池的概念定长内存池的实现整体框架设计threadcachethreadcache整体设计threadcache哈希桶映射对齐规则threadcacheTLS无锁访问centralcachecentralcache整体设计centralcache结构设计centralcache核心实现pagecachepagecache整体设计pagecache中获取Span申请内存过程联调threadcache回收内存centralcache回收内存pagecache回收内存释放内存过程联调大于256K

    2025年8月20日
    5
  • org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode

    org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode

    2021年5月13日
    144
  • Java实现MD5加密的方式

    Java实现MD5加密的方式  MD5加密是一种常见的加密方式,我们经常用在保存用户密码和关键信息上。那么它到底有什么,又什么好处呢,会被这么广泛的运用在应用开发中。  1、什么是MD5  MD5加密全程是Message-DigestAlgoorithm5(信息-摘要算法),它对信息进行摘要采集,再通过一定的位运算,最终获取加密后的MD5字符串。  例如我们要加密一篇文章,那么我们会随机从每段话或者每行中获取…

    2022年7月27日
    11
  • wget、yum、rpm、apt-get区别「建议收藏」

    wget、yum、rpm、apt-get区别

    2022年2月8日
    43
  • PKI系统深入的介绍

    PKI系统深入的介绍

    2021年12月31日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号