这个我们需要自己去编译,但是已经有人帮我们编译好了,压缩算法也已经实现,因此,我们去下载然后编译即可: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 = ; 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() / , bit.getHeight() / ,
Config.ARGB_8888);// 缩小3倍
Canvas canvas = new Canvas(result);
Rect rect = new Rect(, , bit.getWidth(), bit.getHeight());// original
rect = new Rect(, , bit.getWidth() / , bit.getHeight() / );// 缩小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. 使用脚本删除ios工程中未使用图片

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

  2. vs2015web工程中的html引用压缩后css后无法智能提示的问题解决

    环境:win10x64 vs2015企业版 项目:空白web项目(.net framework4) 问题:html页面加入压缩后的css(eg:bootstrap.min.css),编码的时候无法智能 ...

  3. vue开发中vue-resource + canvas 图片压缩、上传、预览

    1.使用vue-resource上传,也可以自定义ajax上传: 2.使用<input type="file" @change="submit()" na ...

  4. iOS中 最新微信支付/最全的微信支付教程详解 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 亲们, 首先让我们来看一下微信支付的流程吧. 1. 注册微信开放平台,创建应用获取appid,appSecret, ...

  5. PyCharm中怎么将非当前工程文件的目录的文件加到当前工程中

    在PyCharm已经建立工程文件的情况下,如果要将一个其他目录的文件导入到已有的工程中,唯一的方法如下: 通过File->Settings->Project->Project Str ...

  6. Android 使用ContentProvider扫描手机中的图片,仿微信显示本地图片效果

    版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/1873 ...

  7. 清除Android工程中没用到的资源

    项目需求一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理 ...

  8. 当Android工程中提示你找不到头文件,但你已经设置头文件路径了

    虽然在Android.mk文件中,配置了LOCAL_C_INCLUDES路径,但是工程中的红色叉号一直提示找不到头文件 这时,你在工程树目录中展开Includes项,捣鼓捣鼓,重新build下,或许就 ...

  9. 清除Android工程中没用到的资源(转)

    项目需求一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理 ...

随机推荐

  1. Ganglia 安装 for centos6.5

    环境: centos6.5x64 ,cdh5.1.0 三个节点: c1:gmeta gmond(gmeta类似于namenode,gmond 相当于datanode)主节点 c2: gmond (相当 ...

  2. p2055&bzoj1433 假期的宿舍

    传送门(洛谷) 传送门(bzoj) 题目 学校放假了······有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如A 和B都是学校的学生,A要回家,而C来看B,C与A不认识. ...

  3. 使用 Chrome Timeline 来优化页面性能

    使用 Chrome Timeline 来优化页面性能 有时候,我们就是会不由自主地写出一些低效的代码,严重影响页面运行的效率.或者我们接手的项目中,前人写出来的代码千奇百怪,比如为了一个 Canvas ...

  4. PCC-S-02201, Encountered the symbol "DB_USER_OPER_COUNT"

    今天编译PROC程序时,遇到这个错误.最后发现原因是.pc文件里声明变量块时,不识别结构体. 今天时间紧知识用第一种方法暂时解决了.晚上抽时间用第二种方法优化一下代码. 查了很多资料,发现只有这个答案 ...

  5. 第三周作业-课本&&视频学习

    <网络攻防技术与实践>第三周作业 Part I 寻找自己留在互联网上的足迹并消除隐私 1.1 google/baidu搜索自己的qq号 搜索结果如图,搜到的有用信息其实就是图上这么几条,能 ...

  6. redis系列:主从复制

    1 简介 这篇文章主要讲述Redis的主从复制功能.会依次从环境搭建.功能测试和原理分析几个方面进行介绍. 2 准备工作 服务器架构图如下 启动主服务器101,使用info replication命令 ...

  7. 【Android-stdio-appdemo搭建记录】

    1-如何删除存在的工程 2-创建Android项目 next设置app兼容最低版本:api15--android 4.0以上 创建活动页面 设置活动页面的名称 创建成功项目以后会有最基本的layout ...

  8. .net core 第一个mvc项目目录结构简析

    创建项目的命令     首先来认识一下创建项目可使用的各种命令,.NETCore 的命令都以 dotnet 打头,这很好理解,输入 dotnet xxx,就是执行环境变量指向的 C:\Program ...

  9. 项目:IT资源共享资源(登录后端)<2>

    公众号技术标签 小程序 PHP 源码 项目 ThinkPHP5.0目录结构,新建一个模块api,该模块下面有controller.model 目录,前者放控制器,写API接口(这里是简单的api写法) ...

  10. MySQL中ORDER BY与LIMIT一起使用(有坑)

    1.  现象与问题 ORDER BY排序后,用LIMIT取前几条,发现返回的结果集的顺序与预期的不一样 下面是我遇到的问题: 可以看到,带LIMIT与不带LIMIT的结果与我预期的不一样,而且“很不可 ...