android全平台编译libjpeg-turbo并基于ANativeWindow加载JPEG图片

libjpeg-turbo使用教程 图像保存为jpg文件。libjpeg-turbo的入门教程。 阅读详情

图形图像实践

概述

libjpeg - turbo是一个JPEG图像编解码器,它使用SIMD指令(MMX,SSE2,AVX2,NEON,AltiVec)来加速x86,x86-64,ARM和PowerPC系统上的基线JPEG压缩和解压缩,以及渐进式JPEG压缩x86和x86-64系统。在这样的系统上, libjpeg - turbo的速度通常是libjpeg的2-6倍,在其他类型的系统上,凭借其高度优化的霍夫曼编码例程, libjpeg - turbo仍然可以大大超过libjpeg

环境准备

操作系统:ubuntu 16.05
ndk版本:android-ndk-r16b

克隆最新的libjpeg - turbo源代码

git clone git@github.com:libjpeg-turbo/libjpeg-turbo.git
  • 去掉版本号

编辑libjpeg-turbo/CMakeLists.txt,注释掉红框中的内容

编辑libjpeg-turbo/sharedlib/CMakeLists.txt,注释掉红框中的内容

第一步:编写配置脚本config.sh

#架构
if [ "$#" -lt 1 ]; then
	THE_ARCH=armv7
else
	THE_ARCH=$(tr [A-Z] [a-z] <<< "$1")
fi

#根据不同架构配置环境变量
case "$THE_ARCH" in
  arm|armv5|armv6|armv7|armeabi)
	TOOLCHAIN_BASE="arm-linux-androideabi"
	HOST="arm-linux-androideabi"
	AOSP_ABI="armeabi"
	AOSP_ARCH="arch-arm"
	AOSP_FLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays"
	PROCESSOR="arm"
	;;
  armv7a|armeabi-v7a)
	TOOLCHAIN_BASE="arm-linux-androideabi"
	HOST="arm-linux-androideabi"
	AOSP_ABI="armeabi-v7a"
	AOSP_ARCH="arch-arm"
	AOSP_FLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays"
	PROCESSOR="arm"
	;;
  armv8|armv8a|aarch64|arm64|arm64-v8a)
	TOOLCHAIN_BASE="aarch64-linux-android"
	HOST="aarch64-linux-android"
	AOSP_ABI="arm64-v8a"
	AOSP_ARCH="arch-arm64"
	AOSP_FLAGS=""
	PROCESSOR="aarch64"
	;;
  x86)
	TOOLCHAIN_BASE="x86"
	HOST="i686-linux-android"
	AOSP_ABI="x86"
	AOSP_ARCH="arch-x86"
	AOSP_FLAGS=""
	PROCESSOR="i386"
	;;
  x86_64|x64)
	TOOLCHAIN_BASE="x86_64"
	HOST="x86_64-linux-android"
	AOSP_ABI="x86_64"
	AOSP_ARCH="arch-x86_64"
	AOSP_FLAGS=""
	PROCESSOR="x86_64"
	;;
  *)
	echo "ERROR: Unknown architecture $1"
	[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
	;;
esac

echo "TOOLCHAIN_BASE="$TOOLCHAIN_BASE
echo "TOOLNAME_BASE="$TOOLNAME_BASE
echo "AOSP_ABI="$AOSP_ABI
echo "AOSP_ARCH="$AOSP_ARCH
echo "AOSP_FLAGS="$AOSP_FLAGS
echo "HOST="$HOST
# Set these variables to suit your needs
NDK_PATH=/media/byhook/backup/android/android-ndk-r10e
BUILD_PLATFORM=linux-x86_64
TOOLCHAIN_VERSION=4.9
ANDROID_VERSION=19

# It should not be necessary to modify the rest
HOST=arm-linux-androideabi
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm
export CFLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays \
  -D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
  -isystem ${NDK_PATH}/sysroot/usr/include \
  -isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
export LDFLAGS=-pie
TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}

cat <<EOF >toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
EOF

cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
  -DCMAKE_POSITION_INDEPENDENT_CODE=1 \
  [additional CMake flags] libjpeg-turbo
make

第二步:编写构建脚本build_jpeg.sh,注意下面的ANDROID_NDK_ROOT路径需要配置成自己的路径

#!/bin/sh

#初始化环境变量
source config.sh

# 获取当前路径
NOW_DIR=$(cd `dirname $0`; pwd)

# 待编译的库目录名称
MY_LIBS_NAME=libjpeg-turbo
# 源代码路径
MY_SOURCE_DIR=$NOW_DIR/libjpeg-turbo

#编译的过程中产生的中间件的存放目录
BINARY_DIR=binary

#NDK路径
ANDROID_NDK_ROOT=/media/byhook/backup/android/android-ndk-r16b
BUILD_PLATFORM=linux-x86_64
AOSP_TOOLCHAIN_SUFFIX=4.9
AOSP_API=21

LIBS_DIR=$NOW_DIR/libs
echo "LIBS_DIR="$LIBS_DIR


# 构建中间文件
BUILD_DIR=./${BINARY_DIR}/${AOSP_ABI}

# 最终编译的安装目录
PREFIX=${LIBS_DIR}/${AOSP_ABI}/
SYSROOT=${ANDROID_NDK_ROOT}/platforms/android-${AOSP_API}/${AOSP_ARCH}

export CFLAGS="$AOSP_FLAGS -D__ANDROID_API__=${AOSP_API} --sysroot=${SYSROOT} \
               -isystem ${ANDROID_NDK_ROOT}/sysroot/usr/include \
               -isystem ${ANDROID_NDK_ROOT}/sysroot/usr/include/${HOST} "
export LDFLAGS=-pie

TOOLCHAIN=${ANDROID_NDK_ROOT}/toolchains/$TOOLCHAIN_BASE-$AOSP_TOOLCHAIN_SUFFIX/prebuilt/${BUILD_PLATFORM}

#创建当前编译目录
mkdir -p ${BUILD_DIR}
mkdir -p ${PREFIX}
cd ${BUILD_DIR}

cat <<EOF >toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR ${PROCESSOR})
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
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

文件目录结构:

第三步:开始执行编译脚本

bash build_jpeg.sh armeabi-v7a

一次编译全平台版本的脚本:build_jpeg_all.sh

for arch in armeabi armeabi-v7a arm64-v8a x86 x86_64
do
    bash build_jpeg.sh $arch
done

加载JPEG图片

新建native-jpeg-turbo工程

定义java层的接口:

package com.onzhou.libjpeg.turbo.loader;

import android.view.Surface;

public class NativeImageLoader {

    static {
        System.loadLibrary("native-image");
    }


    public native void loadJPEGImage(String imagePath, Surface surface);

}

新建native_image.cpp文件,开始编写native层的实现:



#include <jni.h>
#include <stdio.h>
#include <time.h>
#include <android/bitmap.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <jpeglib.h>

#include "native_image.h"

#ifdef ANDROID

#include <android/log.h>
#include <malloc.h>
#include <string.h>

#define LOG_TAG    "NativeImage"
#define LOGE(format, ...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, format, ##__VA_ARGS__)
#define LOGI(format, ...)  __android_log_print(ANDROID_LOG_INFO,  LOG_TAG, format, ##__VA_ARGS__)
#else
#define LOGE(format, ...)  printf(LOG_TAG format "\n", ##__VA_ARGS__)
#define LOGI(format, ...)  printf(LOG_TAG format "\n", ##__VA_ARGS__)
#endif


/**
 * 动态注册
 */
JNINativeMethod methods[] = {
        {"loadJPEGImage", "(Ljava/lang/String;Landroid/view/Surface;)V", (void *) loadJPEGImage}
};

/**
 * 动态注册
 * @param env
 * @return
 */
jint registerNativeMethod(JNIEnv *env) {
    jclass cl = env->FindClass("com/onzhou/libjpeg/turbo/loader/NativeImageLoader");
    if ((env->RegisterNatives(cl, methods, sizeof(methods) / sizeof(methods[0]))) < 0) {
        return -1;
    }
    return 0;
}

/**
 * 加载默认回调
 * @param vm
 * @param reserved
 * @return
 */
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    //注册方法
    if (registerNativeMethod(env) != JNI_OK) {
        return -1;
    }
    return JNI_VERSION_1_6;
}

void ThrowException(JNIEnv *env, const char *exception, const char *message) {
    jclass clazz = env->FindClass(exception);
    if (NULL != clazz) {
        env->ThrowNew(clazz, message);
    }
}

int drawJPEG(const char *input_filename, ANativeWindow_Buffer &nwBuffer) {

    jpeg_decompress_struct jpegInfo;
    jpeg_error_mgr jpegError;
    FILE *input_file;
    JSAMPARRAY buffer;
    int row_width;

    unsigned char *pixel;

    jpegInfo.err = jpeg_std_error(&jpegError);

    if ((input_file = fopen(input_filename, "rb")) == NULL) {
        fprintf(stderr, "can't open %s\n", input_filename);
        LOGE("open file error");
        return -1;
    }

    //初始化对象信息
    jpeg_create_decompress(&jpegInfo);

    //指定图片
    jpeg_stdio_src(&jpegInfo, input_file);

    //读取文件头信息,设置默认的解压参数
    jpeg_read_header(&jpegInfo, TRUE);

    //开始解压
    jpeg_start_decompress(&jpegInfo);

    row_width = jpegInfo.output_width * jpegInfo.output_components;

    buffer = (*jpegInfo.mem->alloc_sarray)((j_common_ptr) &jpegInfo, JPOOL_IMAGE,
                                           row_width, 1);

    //一行
    pixel = (unsigned char *) malloc(row_width);
    memset(pixel, 0, row_width);

    uint32_t *line = (uint32_t *) nwBuffer.bits;
    for (int i = 0; i < jpegInfo.output_height; i++) {
        //读取一行数据
        jpeg_read_scanlines(&jpegInfo, buffer, 1);
        pixel = *buffer;
        //根据缩放选取行
        for (int j = 0; j < jpegInfo.output_width; j++) {
            //存储顺序为BGR,BGR,BGR......
            line[j] = ((uint32_t) pixel[3 * j + 2]) << 16
                      | ((uint32_t) pixel[3 * j + 1] << 8)
                      | ((uint32_t) (pixel[3 * j + 0]));
        }
        line = line + nwBuffer.stride;
    }

    free(pixel);
    //完成解压
    jpeg_finish_decompress(&jpegInfo);

    //销毁解压相关信息
    jpeg_destroy_decompress(&jpegInfo);

    //关闭文件句柄
    fclose(input_file);

    return 0;
}

void loadJPEGImage(JNIEnv *env, jobject obj, jstring jpegPath, jobject surface) {

    const char *path = env->GetStringUTFChars(jpegPath, 0);
    //获取目标surface
    ANativeWindow *window = ANativeWindow_fromSurface(env, surface);
    if (NULL == window) {
        ThrowException(env, "java/lang/RuntimeException", "unable to get native window");
        return;
    }
    //默认的是RGB_565
    int32_t result = ANativeWindow_setBuffersGeometry(window, 0, 0, WINDOW_FORMAT_RGBA_8888);
    if (result < 0) {
        ThrowException(env, "java/lang/RuntimeException", "unable to set buffers geometry");
        //释放窗口
        ANativeWindow_release(window);
        window = NULL;
        return;
    }
    ANativeWindow_acquire(window);

    ANativeWindow_Buffer buffer;
    //锁定窗口的绘图表面
    if (ANativeWindow_lock(window, &buffer, NULL) < 0) {
        ThrowException(env, "java/lang/RuntimeException", "unable to lock native window");
        //释放窗口
        ANativeWindow_release(window);
        window = NULL;
        return;
    }
    //绘制JPEG图片
    drawJPEG(path, buffer);

    //解锁窗口的绘图表面
    if (ANativeWindow_unlockAndPost(window) < 0) {
        ThrowException(env, "java/lang/RuntimeException",
                       "unable to unlock and post to native window");
    }

    env->ReleaseStringUTFChars(jpegPath, path);
    //释放
    ANativeWindow_release(window);
}

注意:上面的操作步骤实际就是:

  • 先通过ANativeWindow_fromSurface拿到对应的窗口
  • 通过libjpeg-turbo库读取对应的JPEG图片,然后解码成对应的RGB数据
  • 最后将解码后的RGB数据写到窗口的buffer中去,完成绘制

编写cmake的配置文件CMakeLists.txt


cmake_minimum_required(VERSION 3.4.1)

##官方标准配置
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -Wall")

add_library(native-image
           SHARED
           src/main/cpp/native_image.cpp)

add_library(jpeg
           SHARED
           IMPORTED)

set_target_properties(jpeg
                    PROPERTIES IMPORTED_LOCATION
                    ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libjpeg.so
                    )

add_library(jpeg-turbo
           SHARED
           IMPORTED)

set_target_properties(jpeg-turbo
                    PROPERTIES IMPORTED_LOCATION
                    ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libturbojpeg.so
                    )

#头文件
include_directories(${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/include)

target_link_libraries(native-image
            jpeg
            jpeg-turbo
            android
            jnigraphics
            log)

在启动的目标Activity中加载我们指定的JPEG图片

mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        NativeImageLoader nativeImageLoader = new NativeImageLoader();
        File file = new File(getExternalFilesDir(null), "input.jpeg");
        nativeImageLoader.loadJPEGImage(file.getAbsolutePath(), holder.getSurface());
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
});

可以看到如下输出:

项目地址:native-jpeg-turbo
https://github.com/byhook/graphic4android

参考:
https://github.com/libjpeg-turbo/libjpeg-turbo/blob/master/BUILDING.md

编译适用于 iOS 平台的 libjpeg-turbo 库 在搜索框中输入 “Header Search Paths”,然后双击空白处,在弹出的对话框中添加 libjpeg-turbo 的头文件路径。接下来,搜索 “Library Search Paths” 并添加 libjpeg-turbo 库文件路径,这通常是 libjpeg-turbo 编译后生成的静态库文件(.a 文件)所在的目录。在 Xcode 中选择 “Build” 或 “Build and Run”,Xcode 将自动开始编译 libjpeg-turbo 库,并将其链接到你的项目中。 阅读详情

相关推荐

libjpeg-turbo库android平台编译

2.准备NDK ,NDK版本小于或者16b 可使用gcc ,大于或者等于17c使用clang。终端输入32.sh进行生成makefile。因为使用GCG方式,所以用NDKR16。make install进行安装。生成makefile成功。成功生成makefile。

777

高性能图片压缩 —— libjpeg-turbo 的编译与集成

前言 Android 提供的 JPEG 压缩, 是由外部链接库中的 libjpeg 实现的, 但 Google 考虑到 Android 设备性能的瓶颈, 在 Skia 调用中的三方链接库 libjpeg 时, 多处进行了阉割处理, 这样带来的好处就是压缩的速度更快了, 但细节丢失严重, 压缩后甚至有偏绿的情况, 下面的代码便是 Android 执行 JPEG 压缩的关键 /** * SkImag...

weixin_33734785的博客 1099

Android编译libjpeg-turbo编程

我们将介绍如何准备编译环境,下载和配置libjpeg-turbo源代码,以及在Android应用程序中使用编译后的库。现在,你可以在应用程序中使用libjpeg-turbo库提供的函数进行JPEG图像的压缩和解压缩操作。现在,您可以在应用程序中使用libjpeg-turbo库提供的函数进行JPEG图像的压缩和解压缩操作。脚本将配置CMake生成的构建脚本,并在指定的输出目录中生成编译后的库文件。脚本将配置CMake生成的构建脚本,并在指定的输出目录中生成编译后的库文件。接下来,在你的Java代码中使用。

CyberLynxX的博客 520

windows 10上源码编译libjpeg-turbo和使用教程

win10编译libjpeg-turbo

weixin_43868576的博客 1697

Android 图片处理:编译和使用 libjpeg

libjpeg 是一个广泛使用的库,用于在 Android 上进行 JPEG 图像的编解码。完成上述步骤后,你可以编译并运行你的 Android 项目。当你点击 “Compress Image” 按钮时,将会调用 JNI 接口,使用 libjpeg 库对输入的图像进行压缩,并将结果保存到输出路径中。通过这个库,你可以轻松地进行 JPEG 图像的编解码和处理。创建一个新的 Android 项目,或者在现有项目中添加 libjpeg 的支持。请确保在运行项目之前,将输入路径和输出路径替换为实际的图像文件路径。

2301_79326930的博客 468

LibjpegTurbo全平台编译.so文件,mac下编译,在Android下最高性能10ms压缩一张1080P图片,x86下更低

此项目是基于Libjpegturbo的编译文件,支持v7a,v8a,x86,x86_64,armeabi。编译环境为mac os , ndk-16b, libjpegturbo-2.0.3版本,cmake 12

android全平台编译libpng并基于ANativeWindow加载PNG图片

http://blog.sina.com.cn/s/blog_85882089010135ta.html

handy周 1618

libyuv 基于libjpeg-turbo

最近libyuv库

Android图片压缩库——libjpeg-turbo

为何Android图片压缩效率低

talkxin的博客 1万+

TESSY创建单元测试或集成测试工程

我们以tessy5.1为例,给大家展示单元测试和集成测试工程的创建过程。

空气中的告白专栏 1686

【深度剖析】三一重工的数字化转型(中篇)

三一重工在数字化转型方面取得了提高效率、降低成本、加强研发创新和改善内控管理等多方面的成效。本研究旨在通过对三一重工数字化转型的深入分析,引导企业思考在第四次工业革命与第三次能源革命交汇的超级技术窗口期,如何进一步把握发展机遇,并为同行业其他企业提供探索性的建议。作为装备制造行业的佼佼者,三一重工的数字化转型受到了业界的广泛关注。作为行业内首批接触并实践数字化转型的企业之一,三一重工的转型经验不仅成功,而且积累了丰富的理论与实践,为其他制造业企业的数字化转型提供了可借鉴的范例。

领信卓越的博客 2306

【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( JNI 传递 Bitmap | 获取位图信息 | 获取图像数据 | 图像数据过滤 | 释放资源 )

一、Bitmap 图像数据处理、 二、Java 层 Bitmap 对象转为 JNI 层 bitmap 对象、 三、获取 bitmap 中的图像数据、 四、过滤 bitmap 中的图像数据 ( 获取 RGB 数据 剔除 A 通道数据 )、 五、释放资源、 六、Bitmap 图像数据处理

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1809

2025-08-19利用opencv检测图片中文字及图片的坐标

该代码实现了图片中中文文本的检测与位置计算功能。主要使用CnOcr库进行OCR识别,结合OpenCV和PIL库处理图像。功能包括:1)检测图片中的中文文本及位置坐标;2)计算每个文本的像素宽度和高度;3)在原图上绘制文本边界框并标注识别结果。代码通过put_chinese_text函数解决中文显示问题,最终输出各文本内容、坐标位置及尺寸信息。适用于需要获取图片中文字精确位置的应用场景。

m0_58149406的博客 395

android 编译 libjpeg-turbo,编译Android环境的libjpeg-turbo

1、libjpeg 和 libjpeg-turbo为了在Android环境实现无损压缩或者我们为了实现更高性能的jpeg图像压缩,我们需要使用到libjpeg-turbo1。官网上已说, libjpeg-turbo is generally 2-6x as fast as libjpeg。所以,一般我们选用libjpeg-turbo而不是libjpeg,因为前者快后者2-6倍2、编译过程2.1 下...

weixin_33977572的博客 791

SolidWorks + AI:利用 DeepSeek AI 自动生成 VBA Macro 宏,实现智能化建模!

本教程介绍如何将集成到插件,实现的自动化操作。通过 DeepSeek AI,您可以快速生成高效的,提升!💡。

SolidWorksAPI的专栏 1万+

Titans:谷歌新型神经记忆架构,突破 Transformer 长序列处理的瓶颈

Titans 是谷歌推出的新型神经网络架构,通过神经长期记忆模块突破 Transformer 在处理长序列数据时的瓶颈,支持并行计算,显著提升训练效率。

士多啤梨先生の博客 991

推荐项目:libjpeg-turbo-android-lib - 优化Android图像处理的利器

`libjpeg-turbo-android-lib`是一个专为Android平台设计的开源库,它基于libjpeg-turbo进行构建,旨在提供更快捷、高效的JPEG图片编码和解码功能。该项目的诞生是为了应对Skia框架在处理JPEG图像时存在的性能问题,通过引入libjpeg-turbo的优势,显著提升了Android应用中的图像处理速度。 查看项目源因:[REASON.md](https:...

gitblog_01110的博客 545

45个经典Linux面试题(非常详细)零基础入门到精通,收藏这一篇就够了

(文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如 i 节点,磁盘分布图,间接块,超级块等。$ chmod 751 file 给 file 的属主分配读、写、执行(7)的权限,给 file 的所在组分配读、执行(5)的权限,给其他用户分配执行(1)的权限。linux命令’hash’管理着一个内置的哈希表,记录了已执行过的命令的完整路径, 用该命令可以打印出你所使用过的命令以及执行的次数。创建文件:典型的如 touch,vi 也可以创建文件,其实只要向一个不存在的文件输出,都会创建文件。

小陈的博客 2071

推荐开源项目:Android平台上的libjpeg-turbo

推荐开源项目:Android平台上的libjpeg-turbo 在高速发展的移动应用领域,图片处理效率是提升用户体验的关键。今天,我们要向大家推荐一个针对Android平台优化的图像压缩库——Android版libjpeg-turbo。虽然原始项目已转移至DeviceFarmer,但其遗留下的这份宝藏依然值得我们深入探讨。 项目介绍 Android版libjpeg-turbo是一个基于libjpe...

gitblog_00091的博客 695

手把手教您如何群晖/飞牛NAS等服务器上一键部署洛雪音乐同步服务,手机电脑无缝同步歌单,支持外网访问

🎵 手机电脑歌单不同步?用Docker在群晖/飞牛NAS等服务器上搭个同步服务器, 3分钟搞定 !支持docker-compose一键部署,手机、电脑、平板收藏夹实时同步,外出也能用域名远程访问 ~ ✨

XiaoqiangClub的博客 4608

从苏宁电器到卡巴斯基(第二部)第01篇:我在卡巴的日子 I

聊聊行业薪酬 我相信不论是谁,如果是入职一家新的公司,那么他最想知道的一件事情就是待遇情况了。这里既包含每月实际能到手多少钱,又包括五险一金是否齐全以及是按照高标准还是低标准缴纳。另外,如果是入职IT公司,还会在意年终奖有多少,毕竟某些富裕的IT企业,每到年末就会以此制造新闻来博取大家的关注,以彰显自身的实力。 一言以蔽之,待遇问题也就是年收入究竟会有多少,也是我们进入职场的人喜欢相互打听的问题。比如我研究生那届最厉害的一位同学,签了A公司的算法岗位,年薪30W+(税前,下同),在当时的我看来就是天价了

Gleam的专栏 1225

Android libjpeg-turbo 项目使用教程

Android libjpeg-turbo 项目使用教程 1. 项目介绍 android-libjpeg-turbo 是一个为 Android 平台提供的独立 Android.mk 构建配置项目,用于集成 libjpeg-turbo 库。libjpeg-turbo 是一个高性能的 JPEG 图像编解码库,能够显著提高图像处理速度。该项目允许你在 Android 应用中使用 ndk-build 来构...

gitblog_00136的博客 1188

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Intel针对AVX2优化了Android仿生库

英特尔的开源技术中心发布了一份白皮书,介绍了当针对AVX2优化Android仿生库时,Android应用程序对支持英特尔的Chromebook的性能影响。 考虑到AVX (Advanced Vector Extensions)(高级矢量扩展)性能优势,我们在Linux桌面上看到了二进制文件支持AVX时的性能优势,特别是在Clear Linux这样的平台上,它真正利用了现代CPU中这些指令集扩展的潜...

weixin_33948416的博客 276

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Android直播开发之旅(15):libjpeg库的编译移植与使用

1. libjpeg介绍  libJPEG库是一款功能强大的JPEG图像处理开源库,它支持将图像数据压缩编码为JPEG格式和对原有的JPEG图像解压缩,Android系统底层处理图片压缩就是用得libJPEG库。但有一点需要注意的是,为了适配低版本的Android手机,Android系统在内部的压缩算法并没有采用普通的哈夫曼(Huffman)算法,因为哈夫曼算法比较占CPU,从而导致Android...

老蒋也疯狂 3560

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

android mjpg格式,Camera常用格式MJPEG和jpeg-turbo库

sam_code@hotmail.comUSB Camera在通过V4L2接口获取Camera数据时,有多种图像格式可选择。但最常用的却是YUV和MJPEG.又因为YUV图片所占空间大,在超过640x480情况下,会超过USB数据传输带宽。所以只能使用MJPEG.现在就谈谈MJPEG相关内容。1. 视频压缩格式:1.1:JPEG (Joint Photographic Experts Group)...

weixin_31974659的博客 2651

Android性能优化——图片压缩的终极选择libjpeg-turbo

文章目录概述需求分析各种压缩方式libjepg-turbo+jnigraphics介绍编译使用引用文章 概述 之前在网络上搜索Android图片压缩,能看到各种各样的关于图片压缩的文章,本没有必要再写一篇,但是最近的一个需求真是折腾了我很久,本来以为很简单的事情,愣是搞了好几天。这里记录下我完成的整个过程,作为一个笔记供以后查阅。如果读友觉得有帮助,就

大帅在唱歌 2682
上一篇: 图解RGB565、RGB555、RGB16、RGB24、RGB32、ARGB32等格式的区别
下一篇: android全平台编译libpng并基于ANativeWindow加载PNG图片
handy周
handy周 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄14年 507粉丝 240原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值