图片压缩最优方案

图片压缩最优方案

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

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


相关推荐

  • 非单页模式下 修改头部显示效果

    非单页模式下 修改头部显示效果

    2022年3月7日
    318
  • laravel 使用create 报错 MassAssignmentException

    laravel 使用create 报错 MassAssignmentException

    2021年10月24日
    46
  • PHP+644是什么,多多自走棋644什么意思

    PHP+644是什么,多多自走棋644什么意思本次给大家带来的是多多自走棋的644相关介绍,很多玩家都不清楚644是什么,这里给大家进行解释,并且会介绍644阵容是什么,应该怎么应对,希望能帮助到各位感兴趣的玩家~多多自走棋644是什么什么是644新版本小伙伴们说的最多的就是644,这套阵容如何无敌,如何变态,如何无解等等。要如何针对与反制644就要先从了解他开始,644就是由6洞洞+4冰川+4萨满三个羁绊效果组合而成。从羁绊拼凑可…

    2022年6月22日
    32
  • 机器学习网格搜索寻找最优参数[通俗易懂]

    机器学习网格搜索寻找最优参数[通俗易懂]整理一下前阶段复习的关于网格搜索的知识:程序及数据请到github上下载GridSearch练习网格搜索是将训练集训练的一堆模型中,选取超参数的所有值(或者代表性的几个值),将这些选取的参数及值全部列出一个表格,并分别将其进行模拟,选出最优模型。上面是数据集的可视化分布图,具体代码如下:%matplotlibinlineimportpandasaspdimpo…

    2022年10月9日
    1
  • siamfc代码解读_每日一文:目标跟踪(SiamFC)「建议收藏」

    siamfc代码解读_每日一文:目标跟踪(SiamFC)「建议收藏」Fully-ConvolutionalSiameseNetworksforObjectTracking.arXiv:1606.09549v2主体结构:核心CNN是AlexNet,去掉padding和全连接层FC,加入BN层,改为全卷积网络FCN,控制stride为8。FCN部分作用相当于特征提取,会得到与输入图像分辨率相关,通道数128的featuremap,类似与常用fHOG特征(h…

    2022年9月1日
    4
  • 多级时间轮定时器_时间轮与哈希表定时

    多级时间轮定时器_时间轮与哈希表定时时间轮简述顾名思义,时间轮就像一个轮子,在转动的时候外界会指向轮子不同的区域,该区域就可以被使用。因此只要将不同时间的定时器按照一定的方法散列到时间轮的不同槽(即时间轮划分的区域)之中,就可以实现在运转到某个槽时,进行判断该定时器是否已经到达运行时间(需要判断是由于有的定时器并非在这一圈就需要运行,可能需要后面几圈才会运行。从图中也可以看出,每个槽中的定时器是以(双向)链表…

    2022年9月29日
    0

发表回复

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

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