这个我们需要自己去编译,但是已经有人帮我们编译好了,压缩算法也已经实现,因此,我们去下载然后编译即可:https://github.com/bither/bither-android-lib

首先将上面下载好的已经编译好的libjpeg放到jni目录下,将下图内容都放到jni目录中: 

安装好ndk以后,直接输入ndk-build即可。接下来就会编译生成生成两个文件夹及文件夹中的arm下的动态库 
 
我的libs中的armeabi和armeabi-v7a中没有生成libbitherjni.so 
libjpegbither.so,不知道哪里出了问题,项目时间紧我就直接把现成的libbitherjni.so,libjpegbither.so文件拷贝进去了。日后研究下为什么ndk-build失败。

二、编写使用类net.bither.util.NativeUtil.java

使用的时候必须在项目中新建一个包net.bither.util,然后加入下面这个类方法,也就是使用了libjpeg开启哈夫曼算法的压缩算法:

/** Copyright 2014 http://Bither.net** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**    http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package net.bither.util;import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;public class NativeUtil {private static int DEFAULT_QUALITY = 95;public static void compressBitmap(Bitmap bit, String fileName,boolean optimize) {compressBitmap(bit, DEFAULT_QUALITY, fileName, optimize);}public static void compressBitmap(Bitmap bit, int quality, String fileName,boolean optimize) {Log.d("native", "compress of native");// if (bit.getConfig() != Config.ARGB_8888) {Bitmap result = null;result = Bitmap.createBitmap(bit.getWidth() / 3, bit.getHeight() / 3,Config.ARGB_8888);// 缩小3倍Canvas canvas = new Canvas(result);Rect rect = new Rect(0, 0, bit.getWidth(), bit.getHeight());// originalrect = new Rect(0, 0, bit.getWidth() / 3, bit.getHeight() / 3);// 缩小3倍canvas.drawBitmap(bit, null, rect, null);saveBitmap(result, quality, fileName, optimize);result.recycle();// } else {// saveBitmap(bit, quality, fileName, optimize);// }
}private static void saveBitmap(Bitmap bit, int quality, String fileName,boolean optimize) {compressBitmap(bit, bit.getWidth(), bit.getHeight(), quality,fileName.getBytes(), optimize);}private static native String compressBitmap(Bitmap bit, int w, int h,int quality, byte[] fileNameBytes, boolean optimize);static {System.loadLibrary("jpegbither");System.loadLibrary("bitherjni");}}

注意包名和方法名都是不能变的,因为在编译的时候已经被确定。 
如果我们想要去修改方法名放入自己的项目中怎么办。那我们就需要去修改一下bitherlibjni.c这个文件。 
例如我想把这个方法放在com.example.test中的ImageUtils中, 
我们只需要把c文件中的

jstring Java_net_bither_util_NativeUtil_compressBitmap(JNIEnv* env,jobject thiz, jobject bitmapcolor, int w, int h, int quality,jbyteArray fileNameStr, jboolean optimize) {

修改为

jstring Java_com_example_test_ImageUtils_compressBitmap(JNIEnv* env,jobject thiz, jobject bitmapcolor, int w, int h, int quality,jbyteArray fileNameStr, jboolean optimize) {

这个对会ndk开发的同学应该都知道,接下来我们重新运行ndk-build就可以重新替换so文件然后调用我们自己的libjpeg了。 
但是,目前libjpeg是很多年前的了。github上这个库只支持arm架构的cpu,如果我们想用这个库的话,只能通过在加载so文件的时候对其进行trycatch处理,来防止x86等其他cpu架构的机器加载so文件报错。

三、调用NativeUtil.java方法进行压缩

NativeUtil.compressBitmap()

public static String compressBitmap(Bitmap image, String filePath){ 
// 最大图片大小 150KB 
int maxSize = 4; 
// 获取尺寸压缩倍数 
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); 
// 循环判断如果压缩后图片是否大于150KB,大于继续压缩 
while (baos.toByteArray().length / 1024 > maxSize) { 
// 重置baos即清空baos 
baos.reset(); 
// 每次都减少10 
options -= 10; 
// 这里压缩options%,把压缩后的数据存放到baos中 
result.compress(Bitmap.CompressFormat.JPEG, options, baos); 

// JNI保存图片到SD卡 这个关键 
String filename = UUID.randomUUID().toString() + “.jpg”; 
String path = filePath + File.separator + filename; 
NativeUtil.saveBitmap(result, options, path, true); 
// 释放Bitmap 
if (!result.isRecycled()) { 
result.recycle(); 

return path; 
}

2.private static void saveBitmap(Bitmap bit, int quality, String fileName, boolean optimize) { 
compressBitmap(bit, bit.getWidth(), bit.getHeight(), quality, fileName.getBytes(), optimize); 

bmp 需要压缩的Bitmap对象, quality压缩质量0-100, fileName 压缩后要保存的文件地址, optimize 是否采用哈弗曼表数据计算 品质相差5-10倍 
该方法就是底层 bitherlibjni.c中的压缩方法

private static native String compressBitmap(Bitmap bit, int w, int h, int quality, byte[] fileNameBytes,boolean optimize);

  3.要注意的地方就是要在build.gradle里面添加下面代码,否则就会报找不到so文件的错误。 
sourceSets { 
main { 
jniLibs.srcDirs = [‘libs’] 

}

Android 在已有工程中实现微信图片压缩相关推荐

  1. android读取工程目录下的文件,Android编程实现读取工程中的txt文件功能

    本文实例讲述了Android编程实现读取工程中的txt文件功能.分享给大家供大家参考,具体如下: 1. 众所周知,Android的res文件夹是用来存储资源的,可以在res文件夹下建立一个raw文件夹 ...

  2. 使用脚本删除ios工程中未使用图片

    使用脚本删除ios工程中未使用图片 最近在读唐巧大神的<iOS开发进阶>,学到了一个大招:使用脚本删除ios中未使用的图片(纸书上有点小问题,参考github上的issue:使用脚本删除i ...

  3. Android Studio之library工程中不能使用switch-case语句访问资源ID

    当我们在Android依赖库中使用switch-case语句访问资源ID时会报如下错误,报的错误是case分支后面跟的参数必须是常数. case expressions must be constan ...

  4. java web工程中如何添加图片_java web中如何添加图片

    java web中如何添加图片 对于java可视化界面插入背景图片只需要background-image:url(图片路径)就行,而对于web项目中,并非如此 效果如下: 我们就需要在jsp页面中写J ...

  5. Android:TextView与EditText中插入表情图片

    表情工具类,用于在TextView与EditText中插入表情图片: public class FaceUtil {public int[] faceIds;public String[] faceC ...

  6. vue中前端实现图片压缩 file文件

    项目中遇到上传图片需要在前端进行图片压缩,将我的实现思路记录一下.(我已经拿到上传的file文件的前提下) 先创建一个公用的js,这里我的是api.js,里面封装一些常用的方法 将图片压缩的方法写到这 ...

  7. android 修改已建工程的api版本,更改API级Android Studio

    哆啦的时光机 如果要在现有项目中更新minSdkVersion ...更新build.gradle(Module: app) - 确保是Gradle脚本下的那个,它不是 build.gradle(Pr ...

  8. android 完美获取音乐文件中的专辑图片并显示

    其实实现音乐中的专辑图像提取是相当的容易的,网上大多的资料都是比较扯淡的,其实就几行代码而已. 看下面代码之前,我们所要做的工作是通过mediaplayer已经获取到了音乐文件中的诸多信息: Medi ...

  9. iOS中常见的图片压缩方法

    1.对图片进行压缩,iOS自带的API提供了函数对图片进行压缩 //两种方法将图片按不同的格式压缩NSData *imageData = UIImageJPEGRepresentation(info[ ...

最新文章

  1. 怎样使用计算机操作,怎么使用键盘快捷键操作电脑
  2. 计算机中算术逻辑单元负责,算术逻辑单元
  3. 给UIButton添加背景图片
  4. 什么是微服务_微服务系列笔记:什么是微服务?
  5. 如何将hive与mysql连接_hive连接mysql配置
  6. 如何访问云端的tcpserver_远程读写FTP文件,花生壳盒子+Serv-U快速实现远程访问...
  7. Angular开发实践(五):深入解析变化监测
  8. 在Unity中实现屏幕空间反射Screen Space Reflection(2)
  9. window 服务(三)
  10. 为什么都建议学java而不是python-为什么java比python复杂,还是有很多人选择学习java?...
  11. Java POI Word 写文档
  12. ASP.NET Web Pages:WebGrid 帮助器
  13. URI和URL的区别和关联
  14. 计算机图标被选定无法取消,我电脑桌面上图标全被选中的状态,去不掉怎么处理?...
  15. 使用Truetype字体制作ArcGIS符号
  16. 住宅ip代理和数据中心代理的区别是什么?
  17. oracle系统优化
  18. UDS04-清除诊断信息服务【ServiceID = 0x14】
  19. MAC + IDEA自动生成SerialVersionUID(亲测有效)
  20. 最长公共子序列的问题

热门文章

  1. ios创建自定义控件必须具备的三个方法
  2. iOS协议、代理、Block和回调、类别
  3. c++ const常量的实现机制(转载)2
  4. C#生成不重复随机数列表
  5. Microsoft SQL Server 2008技术内幕:T-SQL查询---------逻辑查询处理
  6. Notadd —— 基于 nest.js 的微服务开发框架
  7. [小程序]_ELVE_小程序开发(1)
  8. 开源一个ReactNative日历控件
  9. Haproxy反向代理WebSocket的方法
  10. apache2.4.18中启用h2c