图片压缩最优方案

图片压缩最优方案

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

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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【转载】面试?或许你应该这样

    【转载】面试?或许你应该这样

    2021年11月20日
    52
  • 规范化理论:多值依赖的理解_依赖关联泛化实现

    规范化理论:多值依赖的理解_依赖关联泛化实现多值依赖的定义我们用一个例子来引出多值依赖(MultivaluedDependency,MVD)的含义。假设学校中一门课程可由多名教师讲授,教学中他们使用相同的一套参考书,这样我们可用下图的非规范化的关系来表示课程C、教师T和参考书B间的关系。关系CTB如果关系CIB转化成规范化的关系,如图所示。规范后的关系CTB由此可以看出,规范后的关系模式…

    2025年7月28日
    2
  • Windows留后门–教程(五)——shift粘贴键后门

    Windows留后门–教程(五)——shift粘贴键后门一、shift粘贴键后门介绍Shift粘滞键是当用户连按5次shift就会自动弹出的一个程序,其实不光是粘滞键,还有各种辅助功能,这类辅助功能都拥有一个特点就是当用户未进行登录时也可以触发。所以攻击者很有可能通过篡改这些辅助功能的指向程序来达到权限维持的目的。(辅助功能镜像劫持是一样的原理)二、shift粘贴键后门-教程前提条件:假设在攻击的过程中通过利用各种getshell,已经拿到目标服务器administrator权限靶机:windowsServer2012IP:192.168.2

    2025年11月19日
    5
  • 《剑指offer》答案整理

    《剑指offer》答案整理

    2021年10月5日
    59
  • AndroidStudio-断点调试-让你的调试更有效率

    AndroidStudio-断点调试-让你的调试更有效率前言:上篇博客AndroidStudio-断点调试-也许你该知道断点调试是有多么的美好,记录了AndroidStudio上断点调试的基本流程和debug面板按钮介绍.这一篇就给大家分享一点调试的小技巧,让我们的代码调试变得更有效率.你可以选择随时进入调试模式一般我们都是点击绿色小昆虫进入调试模式进行调试,其实还可以有另外一种方法.看下面的面板截图,有没有发现有两个小昆虫图标.图标E

    2022年5月21日
    60
  • Redis Sentinel实现Failover

    Redis Sentinel实现Failover

    2021年9月9日
    66

发表回复

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

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