亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

性能優(yōu)化 (四) ubuntu 完美編譯 libjpeg 圖像壓縮庫(kù),媲美微信圖片壓縮算法

2json / 3529人閱讀

摘要:但是為了能夠適配低端的手機(jī)這里的低端是指以前的硬件配置不高的手機(jī),和內(nèi)存在手機(jī)上都非常吃緊,性能差,由于哈夫曼算法比較吃并且編解碼慢,被迫用了其他的算法。

使用方式

    在 project/build.gradle 上添加以下代碼

    allprojects {
    		repositories {
    			...
    			maven { url "https://jitpack.io" }
    		}
    	}
    

    在 app/build.gradle 添加依賴

    dependencies {
            implementation "com.github.yangkun19921001:LIBJPEG_SAMPLE:v1.0.1"
    }
    

    壓縮使用

    //bitmap        : 需要壓縮的 bitmap
    //q             : 壓縮質(zhì)量 建議 30 - 50
    //outputFilePath: 壓縮之后存儲(chǔ)的圖片地址
    JpegUtils.native_Compress(Bitmap bitmap,int q,String outputFilePath);
    

JEPG 是什么");

相信有一部分使用 iPhone 手機(jī)用微信發(fā)送圖片的時(shí)候,明明圖片大小只有 1M ,但清晰度比 Android 手機(jī) 5 M 圖片大小的還要清晰,那么這是為什么呢 ?。

當(dāng)時(shí)谷歌開發(fā) Android 的時(shí)候,考慮了大部分手機(jī)的配置并沒有那么高,所以對(duì)圖片處理使用的是 Skia。當(dāng)然這個(gè)庫(kù)的底層還是用的 jpeg 圖片壓縮處理。但是為了能夠適配低端的手機(jī)(這里的低端是指以前的硬件配置不高的手機(jī),CPU 和內(nèi)存在手機(jī)上都非常吃緊,性能差),由于哈夫曼算法比較吃 CPU 并且編解碼慢,被迫用了其他的算法。所以 Skia 在進(jìn)行圖片處理在低版本中并沒有開啟哈弗曼算法。

那么,JEPG 到底是什么?JEPG (全稱是 Joint Photographic Experts Group) 是一種常見的一種圖像格式,為什么我在這里會(huì)提到 JEPG 呢?是因?yàn)殚_源了一個(gè) C/C++ 庫(kù)底層是基于哈夫曼算法對(duì)圖片的壓縮 (libjpeg),下面我們就來著重了解下 libjpeg 這個(gè)庫(kù)

libjpeg 簡(jiǎn)介

libjpeg-turbo 是一個(gè) JPEG 圖像編解碼器,它使用 SIMD 指令(MMX,SSE2,AVX2,NEON,AltiVec)來加速 x86,x86-64,ARM 和 PowerPC 系統(tǒng)上的基線 JPEG 壓縮和解壓縮,以及漸進(jìn)式JPEG 壓縮 x86 和 x86-64 系統(tǒng)。在這樣的系統(tǒng)上,libjpeg-turbo 的速度通常是 libjpeg 的 2 - 6 倍,其他條件相同。在其他類型的系統(tǒng)上,憑借其高度優(yōu)化的霍夫曼編碼例程,libjpeg-turbo 仍然可以大大超過 libjpeg。在許多情況下,libjpeg-turbo 的性能可與專有的高速 JPEG 編解碼器相媲美。 libjpeg-turbo 實(shí)現(xiàn)了傳統(tǒng)的 libjpeg API 以及功能較弱但更直接的 TurboJPEG API 。 libjpeg-turbo 還具有色彩空間擴(kuò)展,允許它從/解壓縮到32位和大端像素緩沖區(qū)(RGBX,XBGR等),以及功能齊全的 Java 接口。 libjpeg-turbo 最初基于 libjpeg / SIMD,這是由 Miyasaka Masaru 開發(fā)的 libjpeg v6b 的 MMX 加速衍生物。 TigerVNC 和 VirtualGL 項(xiàng)目在 2009 年對(duì)編解碼器進(jìn)行了大量增強(qiáng),并且在2010年初,libjpeg-turbo 分拆成一個(gè)獨(dú)立項(xiàng)目,目標(biāo)是為更廣泛的用戶提供高速 JPEG壓縮/解壓縮技術(shù)。開發(fā)人員。

現(xiàn)在我們大概了解到了 libjpeg 是一個(gè)對(duì)圖像編解碼庫(kù),現(xiàn)在我們需要準(zhǔn)備環(huán)境去編譯 libjpeg。

編譯準(zhǔn)備工作

系統(tǒng): Ubuntu 18.04 也可以使用我下載好的 提取碼:biyt

libjpeg: libjepg 2.0.2

cmake: cmake-3.14.4-Linux-x86_64.tar.gz

ndk: android-ndk-r17c

開始發(fā)車準(zhǔn)備編譯

    ubuntu 中下載 libjpeg

      wget github.com/libjpeg-tur…

      解壓 tar xvf 2.0.2.tar.gz

      編譯參考

    ubuntu 中安裝 cmake

      刪除原來的 apt-get autoremove cmake

      wget github.com/Kitware/CMa…

      解壓 tar zxvf cmake-3.14.3.tar.gz

      創(chuàng)建軟連接

        mv cmake-3.14.3-Linux-x86_64 /opt/cmake-3.14.3

        ln -sf /opt/cmake-3.14.3/bin/* /usr/bin/

      輸入 cmake -- version 如果有這樣的顯示代表安裝成功

    進(jìn)入到 libjpeg 目錄,生成 shell 腳本

      vim build.sh 新建一個(gè)文件

      # lib-name
      MY_LIBS_NAME=libjpeg-turbo_2.0.2
      # 源碼目錄
      MY_SOURCE_DIR=/home/yangkun/libjpeg-turbo-2.0.2
      MY_BUILD_DIR=yangkun
      
      # android-cmake
      CMAKE_PATH=/opt/cmake-3.14.4/bin
      
      export PATH=${CMAKE_PATH}/bin:$PATH
      
      NDK_PATH=/home/yangkun//android-ndk-r17c
      BUILD_PLATFORM=linux-x86_64
      TOOLCHAIN_VERSION=4.9
      ANDROID_VERSION=24
      
      ANDROID_ARMV5_CFLAGS="-march=armv5te"
      ANDROID_ARMV7_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"  # -mfpu=vfpv3-d16  -fexceptions -frtti
      ANDROID_ARMV8_CFLAGS="-march=armv8-a"  	# -mfloat-abi=softfp -mfpu=neon -fexceptions -frtti
      ANDROID_X86_CFLAGS="-march=i386 -mtune=intel -mssse3 -mfpmath=sse -m32"
      ANDROID_X86_64_CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"
      
      # params($1:arch,$2:arch_abi,$3:host,$4:compiler,$5:cflags,$6:processor)
      build_bin() {
      
          echo "-------------------star build $2-------------------------"
      
          ARCH=$1                # arm arm64 x86 x86_64
          ANDROID_ARCH_ABI=$2    # armeabi armeabi-v7a x86 mips
          # 最終編譯的安裝目錄
          PREFIX=$(pwd)/dist/${MY_LIBS_NAME}/${ANDROID_ARCH_ABI}/
          HOST=$3
          COMPILER=$4
          PROCESSOR=$6
          SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-${ARCH}
          CFALGS="$5"
          TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
          
          # build 中間件
          BUILD_DIR=./${MY_BUILD_DIR}/${ANDROID_ARCH_ABI}
      
          export CFLAGS="$5 -Os -D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} 
                         -isystem ${NDK_PATH}/sysroot/usr/include 
                         -isystem ${NDK_PATH}/sysroot/usr/include/${HOST} "
          export LDFLAGS=-pie
      
          echo "path==>$PATH"
          echo "build_dir==>$BUILD_DIR"
          echo "ARCH==>$ARCH"
          echo "ANDROID_ARCH_ABI==>$ANDROID_ARCH_ABI"
          echo "HOST==>$HOST"
          echo "CFALGS==>$CFALGS"
          echo "COMPILER==>$COMPILER-gcc"
          echo "PROCESSOR==>$PROCESSOR"
      
          mkdir -p ${BUILD_DIR}   #創(chuàng)建當(dāng)前arch_abi的編譯目錄,比如:binary/armeabi-v7a
          cd ${BUILD_DIR}         #此處 進(jìn)了當(dāng)前arch_abi的2級(jí)編譯目錄
      
      #運(yùn)行時(shí)創(chuàng)建臨時(shí)編譯鏈文件toolchain.cmake
      cat >toolchain.cmake << EOF 
      set(CMAKE_SYSTEM_NAME Linux)
      set(CMAKE_SYSTEM_PROCESSOR $6)
      set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${COMPILER}-gcc)
      set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${COMPILER})
      EOF
      
          cmake -G"Unix Makefiles" 
                -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake 
                -DCMAKE_POSITION_INDEPENDENT_CODE=1 
                -DCMAKE_INSTALL_PREFIX=${PREFIX} 
                -DWITH_JPEG8=1 
                ${MY_SOURCE_DIR}
      
          make clean
          make
          make install
      
          #從當(dāng)前arch_abi編譯目錄跳出,對(duì)應(yīng)上面的cd ${BUILD_DIR},以便function多次執(zhí)行
          cd ../../
      
          echo "-------------------$2 build end-------------------------"
      }
      
      # build armeabi
      build_bin arm armeabi arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV5_CFLAGS" arm
      
      #build armeabi-v7a
      build_bin arm armeabi-v7a arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV7_CFLAGS" arm
      
      #build arm64-v8a
      build_bin arm64 arm64-v8a aarch64-linux-android aarch64-linux-android "$ANDROID_ARMV8_CFLAGS" aarch64
      
      #build x86
      build_bin x86 x86 x86 i686-linux-android "$ANDROID_X86_CFLAGS" i386
      
      #build x86_64
      build_bin x86_64 x86_64 x86_64 x86_64-linux-android "$ANDROID_X86_64_CFLAGS" x86_64
      

      如果編譯遇見 權(quán)限問題

      給它一個(gè) 可執(zhí)行文件的權(quán)限 chmod +x build.sh

      繼續(xù)執(zhí)行

      編譯完成

      這里我們發(fā)現(xiàn) 已經(jīng)有我們需要的 靜態(tài)庫(kù) .a 和 動(dòng)態(tài)庫(kù) .so

      在 AndroidStudio 中創(chuàng)建一個(gè)簡(jiǎn)單的項(xiàng)目 用于測(cè)試是否壓縮成功

        結(jié)構(gòu)目錄

      標(biāo)紅的都是重要的文件,include 頭文件和 libs/armeabi-v7a 是我們剛剛編譯出來的文件

      下面我們就來運(yùn)行一下看看壓縮效果

        壓縮主要代碼

        jni 代碼

        #include 
        #include 
        #include "../include/jpeglib.h"
        #include 
        #include 
        
        
        void write_JPEG_file(uint8_t *data, int w, int h, jint q, const char *path) {
        //    3.1、創(chuàng)建jpeg壓縮對(duì)象
            jpeg_compress_struct jcs;
            //錯(cuò)誤回調(diào)
            jpeg_error_mgr error;
            jcs.err = jpeg_std_error(&error);
            //創(chuàng)建壓縮對(duì)象
            jpeg_create_compress(&jcs);
        //    3.2、指定存儲(chǔ)文件  write binary
            FILE *f = fopen(path, "wb");
            jpeg_stdio_dest(&jcs, f);
        //    3.3、設(shè)置壓縮參數(shù)
            jcs.image_width = w;
            jcs.image_height = h;
            //bgr
            jcs.input_components = 3;
            jcs.in_color_space = JCS_RGB;
            jpeg_set_defaults(&jcs);
            //開啟哈夫曼功能
            jcs.optimize_coding = true;
            jpeg_set_quality(&jcs, q, 1);
        //    3.4、開始?jí)嚎s
            jpeg_start_compress(&jcs, 1);
        //    3.5、循環(huán)寫入每一行數(shù)據(jù)
            int row_stride = w * 3;//一行的字節(jié)數(shù)
            JSAMPROW row[1];
            while (jcs.next_scanline < jcs.image_height) {
                //取一行數(shù)據(jù)
                uint8_t *pixels = data + jcs.next_scanline * row_stride;
                row[0] = pixels;
                jpeg_write_scanlines(&jcs, row, 1);
            }
        //    3.6、壓縮完成
            jpeg_finish_compress(&jcs);
        //    3.7、釋放jpeg對(duì)象
            fclose(f);
            jpeg_destroy_compress(&jcs);
        }
        
        
        extern "C"
        JNIEXPORT void JNICALL
        Java_com_yk_libjpeg_1sample_libjpeg_JpegUtils_native_1Compress__Landroid_graphics_Bitmap_2ILjava_lang_String_2(
                JNIEnv *env, jclass type, jobject bitmap, jint q, jstring path_) {
            const char *path = env->GetStringUTFChars(path_, 0);
            //從bitmap獲取argb數(shù)據(jù)
            AndroidBitmapInfo info;//info=new 對(duì)象();
            //獲取里面的信息
            AndroidBitmap_getInfo(env, bitmap, &info);//  void method(list)
            //得到圖片中的像素信息
            uint8_t *pixels;//uint8_t char    java   byte     *pixels可以當(dāng)byte[]
            AndroidBitmap_lockPixels(env, bitmap, (void **) &pixels);
            //jpeg argb中去掉他的a ===>rgb
            int w = info.width;
            int h = info.height;
            int color;
            //開一塊內(nèi)存用來存入rgb信息
            uint8_t *data = (uint8_t *) malloc(w * h * 3);//data中可以存放圖片的所有內(nèi)容
            uint8_t *temp = data;
            uint8_t r, g, b;//byte
            //循環(huán)取圖片的每一個(gè)像素
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    color = *(int *) pixels;//0-3字節(jié)  color4 個(gè)字節(jié)  一個(gè)點(diǎn)
                    //取出rgb
                    r = (color >> 16) & 0xFF;//    #00rrggbb  16  0000rr   8  00rrgg
                    g = (color >> 8) & 0xFF;
                    b = color & 0xFF;
                    //存放,以前的主流格式j(luò)peg    bgr
                    *data = b;
                    *(data + 1) = g;
                    *(data + 2) = r;
                    data += 3;
                    //指針跳過4個(gè)字節(jié)
                    pixels += 4;
                }
            }
            //把得到的新的圖片的信息存入一個(gè)新文件 中
            write_JPEG_file(temp, w, h, q, path);
        
            //釋放內(nèi)存
            free(temp);
            AndroidBitmap_unlockPixels(env, bitmap);
            env->ReleaseStringUTFChars(path_, path);
        }
        

        調(diào)用代碼

        public class JpegUtils {
            static {
                System.loadLibrary("jpeg-yk");
            }
        
            /**
             * A native method that is implemented by the "native-lib" native library,
             * which is packaged with this application.
             */
            public native  static void native_Compress(Bitmap bitmap, int q, String path);
        
        }
        

效果

    開始?jí)嚎s

        public void click(View view) {
            File input = new File(Environment.getExternalStorageDirectory(), "/girl.jpg");
            ImageView preImg = findViewById(R.id.pre);
            mNextImg = findViewById(R.id.next);
            inputBitmap = BitmapFactory.decodeFile(input.getAbsolutePath());
            preImg.setImageBitmap(inputBitmap);
           JpegUtils .native_Compress(inputBitmap, 10, Environment.getExternalStorageDirectory() + "/girl4.jpg");
            Toast.makeText(this, "執(zhí)行完成", Toast.LENGTH_SHORT).show();
            String filePath = Environment.getExternalStorageDirectory() + "/girl4.jpg";
            mNextImg.setImageBitmap(BitmapFactory.decodeFile(filePath));
        }
    

    動(dòng)畫效果

    壓縮效果: 壓縮質(zhì)量在 10 的時(shí)候用壓縮出來的質(zhì)量也還是挺好了,只有周圍有點(diǎn)點(diǎn)模糊,但是建議壓縮質(zhì)量在 30 -50 之間。

    壓縮率: 大約壓縮后的圖片大小是原圖的縮小 6 倍的樣子。

資料 更多代碼信息請(qǐng)移步 GitHub 提供 libjpeg 編譯腳本 libjpeg 編譯的源碼和動(dòng)態(tài)/靜態(tài)庫(kù) 在 dist 目錄 提取碼:b0cs 計(jì)劃

圖片優(yōu)化計(jì)劃出三篇文章

    libjpeg 編譯及使用

    長(zhǎng)圖巨圖優(yōu)化

    bitmap 內(nèi)存管理 三級(jí)緩存

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/6819.html

相關(guān)文章

  • 精彩文章大合集- 收藏集 - 掘金

    摘要:發(fā)布應(yīng)用市場(chǎng)的平臺(tái)搶紅包工具紅包精靈開源啦掘金紅包精靈,如果喜歡,點(diǎn)個(gè)開源不易。作者將原素材文章進(jìn)行了新內(nèi)容的添加和重新排列,但是因?yàn)槲恼赂咝У拇a編寫技巧總結(jié)前端掘金本文總結(jié)了代碼編寫技巧,來提升你的和代碼。 收藏安卓開發(fā)中非常實(shí)用優(yōu)秀的庫(kù)! 有圖有真相! - Android - 掘金本來是打算收藏工具類的,但轉(zhuǎn)念一想,已經(jīng)有這么多優(yōu)秀的庫(kù)了,就沒必要再去重復(fù)造輪子了,便歸納工作中比...

    ermaoL 評(píng)論0 收藏0
  • Google I/O 2016 筆記之圖像壓縮

    摘要:寫在前面開發(fā)中的圖像壓縮是一個(gè)很重要的部分。而這篇文章會(huì)讓我們從另外一個(gè)角度來認(rèn)識(shí)平臺(tái)下的圖像壓縮和優(yōu)化。所以,它是你圖像壓縮和優(yōu)化的首選,盡可能的去使用吧。 寫在前面 Android開發(fā)中的圖像壓縮是一個(gè)很重要的部分。而這篇文章會(huì)讓我們從另外一個(gè)角度來認(rèn)識(shí)Android平臺(tái)下的圖像壓縮和優(yōu)化。 這篇文章更適合和設(shè)計(jì)師一起來看,所以,如果你和你的設(shè)計(jì)師是好基友的話,不妨叫上他,倒兩杯咖...

    BWrong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<