图片压缩最优方案

图片压缩最优方案

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

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月1日 下午9:00
下一篇 2022年3月1日 下午10:00


相关推荐

  • 主题:Windows系统服务器磁盘挂载

    主题:Windows系统服务器磁盘挂载

    2021年9月22日
    162
  • intellij idea 安装教程_intellij idea2021安装教程

    intellij idea 安装教程_intellij idea2021安装教程1百度搜索idea2点击进入3选择旗舰版下载4点击安装5安装6激活点击桌面图标后,接受什么的,点击LICENSESERVER,(忘了截图,原谅我),输入http://idea.congm.in点击active即可。7配置(很重要,你的使用体验全部来自于此)7.1设置常见视图…

    2022年10月2日
    7
  • Java Bean详解

    Java Bean详解JavaBean是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。众所周知,属性名称符合这种模式,其他Java类可以通过自省机制(反射机制)发现和操作这些JavaBean的属性。功能特点用户可以使…

    2022年6月12日
    26
  • psutil 3.0

    psutil 3.0Hereweare.It’sbeenalongtimesincemylastblogpostandmylastpsutilrelease.Thereason?I’vebeentravelling!Imean…alot.I’vespent3monthsinBerlin,3weeksinJapanand2monthsin…

    2022年6月10日
    33
  • 分支定界法(matlab实现)

    分支定界法(matlab实现)分支定界法背景今天利用 matlab 来实现求解完全整数规划问题和混合整数规划问题的分支定界法 基本理论分支定界法 用以求解整数规划问题的一种方法 求解步骤 求出该整数规划问题对应的原线性规划问题的最优解 若为整数 得到最优解 若不为整数 跳至第 2 步分支 定界 剪枝 不断反复 直到得到整数最优解分支定界法伪代码如下 输入规划问题对应的矩阵 binTreeNode f

    2026年3月20日
    2
  • 数据库迁移常见的四种方法

    数据的迁移就像搬家,基本每个用过手机的人都做过数据迁移,将旧智能手机中的电话号码、照片、微信聊天记录导入到另一台新的智能手机。因此数据迁移并不神秘。在上云的过程中,因数据的量更大、数据重要性更大、专业性更强,因此在公有云上诞生了“云迁移”这项目服务,在公有云市场也有上百个云服务商专业做“云迁移”服务。今天我们来讲三种常用的云数据库迁移方法。一、为什么做云迁…

    2022年4月5日
    119

发表回复

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

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