[JNI]开发实例(1)封装libjpeg库 保证图片质量压缩图片

原创 2017年03月04日 15:45:21

为什么libjpeg这么好用,这里不做介绍了,自行去搜索很多blog有介绍,也可以反编译微信,淘宝等大厂app,你都会发现libjpeg.so的身影。

直接上代码撸

环境:
android studio 2.2.3

下载编译好的libjpeg.so

当然你也可以下载libjpeg.a静态文件,然后把你的jni与这个.a打成一个so库;
这里为了方便就直接下载github上编译好的so文件了,你也可以尝试自己编译libjpeg.so

https://github.com/libjpeg-turbo/libjpeg-turbo

接下来就该创建ndk工程了,如果你看过前面几篇文章,创建工程应该不是问题。

配置cmakeList.xml

cmake_minimum_required(VERSION 3.4.1)


add_library(
             hjpeg

             SHARED

             src/main/cpp/native-lib.cpp )

#include 这个目录下所有的文件
include_directories(src/main/cpp/include)

#导入jpeg动态库 SHARED;静态库为STATIC
add_library(jpeg SHARED IMPORTED )

#对应so目录 这里为了方便写死的路径,只编译armeabi-v7a包
set_target_properties(jpeg PROPERTIES IMPORTED_LOCATION ../../../../libs/armeabi-v7a/libjpeg.so)

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )


target_link_libraries( # Specifies the target library.
                       hjpeg
                       jpeg
                       #jnigraphics这个是android下面的bitmap.h对应的库
                       jnigraphics
                       ${log-lib})

gradle配置:
只编译armeabi-v7a包

  ndk {
            abiFilters  'armeabi-v7a'
       }

拷贝.h文件到cpp目录下
这里写图片描述

只用到这几个h文件,你可以去github下载下来的文件夹找出这些文件,也可以从我demo中拷贝过去。

准备工作就做完了,接下来开始编码

java 层创建一个ImageUtils.java


public class ImageUtils {


    static {
        System.loadLibrary("hjpeg");//对应cmakelist中配置的名称
    }


    public static native boolean compressBitmap(Bitmap bitmap, int width, int height, String filePath,int quality);
}

编写cpp文件:

Java_com_honjane_compress_utils_ImageUtils_compressBitmap(JNIEnv *env, jclass jcls, jobject bitmap,
                                                          jint width, jint height,
                                                          jstring jfilepath,
                                                          jint quality) {

    AndroidBitmapInfo infoColor;
    BYTE *pixelColor;
    BYTE *data;
    BYTE *tempData;

    const char *filepath = env->GetStringUTFChars(jfilepath, 0);
    LOGE("------ 文件目录 %s", filepath);
    if ((AndroidBitmap_getInfo(env, bitmap, &infoColor)) < 0) {
        LOGE("parse error");
        env->ReleaseStringUTFChars(jfilepath, filepath);
        return false;
    }
    //锁住 与操作canvas类似,操作前先锁住
    if ((AndroidBitmap_lockPixels(env, bitmap, (void **) &pixelColor)) < 0) {
        LOGE("lock pixels error");
        env->ReleaseStringUTFChars(jfilepath, filepath);
        return false;
    }

    BYTE r, g, b;
    int color;
    data = (BYTE *) malloc(width * height * 3);
    //获取bitmap对应的rgb值 存入data
    tempData = data;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            color = *((int *) pixelColor);
            //获取对应的r,g,b值,其中a为高8位  color >> 24
            r = ((color & 0x00FF0000) >> 16);//r为次高8位  color >> 16
            g = ((color & 0x0000FF00) >> 8); //g为中8位  color >> 8
            b = color & 0X000000FF;          //b为低8位

            *data = b;
            *(data + 1) = g;
            *(data + 2) = r;
            data += 3;
            pixelColor += 4;
        }
    }
    //释放锁
    AndroidBitmap_unlockPixels(env, bitmap);
    int resultCode = generateJPEG(tempData, width, height, quality, filepath, true);
    LOGE("------压缩完成 0 失败 ,1 成功 resultCode= %d", resultCode);

    free(tempData);
    if (resultCode == 0) {
        env->ReleaseStringUTFChars(jfilepath, filepath);
        return false;
    }

    env->ReleaseStringUTFChars(jfilepath, filepath);

    return true;
}

主要有这几个步骤:
1、将bitmap解码并转换为RGB数据
2、为JPEG对象分配空间并初始化
3、获取文件信息
4、指定压缩数据源
5、为压缩设定参数,包括图像大小,颜色空间
6、开始压缩
7、压缩完毕
8、释放资源
代码中在对应位置有做注释,请对照代码阅读。

效果:
这里写图片描述

代码地址:
https://github.com/honjane/android-libjpeg

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android_NDK图片压缩之Libjpeg库使用

一、前言 Android图片压缩处理确实不如Ios,之前完全没听过libjpeg这个东西,工作闲余时间研究了了一天,总结下吧 libjpeg的介绍可以参考文章:http://blog.csdn.ne...
  • hqiong208
  • hqiong208
  • 2016年12月15日 15:59
  • 4094

Imagick 图片压缩质量(优于writeImages)

  • wsliangjian
  • wsliangjian
  • 2015年12月30日 17:14
  • 429

Bitmap压缩原理解析与Android 7.0之前通过NDK使用libjpeg库高质量压缩图片

一、Bitmap压缩原理 我们平常使用的bitmap.compress() 的内部实际上调用了如下native方法 private static native boolean nativeComp...
  • SakuraMashiro
  • SakuraMashiro
  • 2018年01月27日 18:22
  • 68

linux libjpeg对图像进行压缩

libjpeg 是一个完全用C语言编写的库,包含了被广泛使用的JPEG解码、JPEG编码和其他的JPEG功能的实现。Libjpeg不仅可以把bmp格式转化成jpg格式,还支持其他格式的转化成jpg格式...
  • manchestermi
  • manchestermi
  • 2016年03月06日 18:31
  • 901

图片质量压缩,尺寸不变,不需要用到磁盘

项目遇到一个很刁钻的问题,系统有个上传图片的功能,但是为了节省带宽,必须限制用户输入图片的大小,为了用户的体验,用户上传任意一张图片都要被允许,并且不能使用磁盘。这个刁钻的问题解决方法只有在用户上传图...
  • u014476088
  • u014476088
  • 2017年06月20日 12:21
  • 373

Android压缩图片和libjpeg库

前言 一些额外知识 补充知识的结论 参考文献 前言: 在android开发时我们往往有如对图片如下的需求: 1. 希望压缩图片方便网络传输 2. 修改图片分辨率 防止在Andr...
  • qfanmingyiq
  • qfanmingyiq
  • 2017年09月01日 00:16
  • 2993

使用libjpeg对图像进行压缩

libjpeg 是一个完全用C语言编写的库,包含了被广泛使用的JPEG解码、JPEG编码和其他的JPEG功能的实现。Libjpeg不仅可以把bmp格式转化成jpg格式,还支持其他格式的转化成jpg格式...
  • jwzhangjie
  • jwzhangjie
  • 2013年04月12日 12:34
  • 4509

js实现图片质量压缩demo

XMLHttpRequest上传文件 /* 三个参数 file:一个是文件(类型是图片格式), w:一个是文件...
  • haoaiqian
  • haoaiqian
  • 2017年12月28日 13:58
  • 219

java 等比例 改变图片的质量(等大小压缩图片)

java 等比例 改变图片的质量(等大小压缩图片)
  • WD4871
  • WD4871
  • 2016年06月01日 16:37
  • 735

Android使用libjpeg实现图片压缩

一、Android中使用的图片压缩库 Android和IOS 中图片处理使用了一个叫做skia的开源图形处理引擎。他位于android源码的/external/skia 目录。我们平时在java层使...
  • a992036795
  • a992036795
  • 2016年12月22日 15:39
  • 3969
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[JNI]开发实例(1)封装libjpeg库 保证图片质量压缩图片
举报原因:
原因补充:

(最多只允许输入30个字)