編輯:關於Android編程
libjpeg是一個被廣泛使用的JPEG解碼、JPEG編碼和其他的JPEG功能的實現庫。
說它使用廣泛,是因為它跨了很多平台。比如Linux平台、JDK、Android和其他庫如tess-two等等。
最近正在研究Android中直接用C/C++將圖片的字節數組保存成圖片,libjpeg庫十分擅長。
官網www.ijg.org下載最新的版本9b,解壓後會看到數量眾多makefile,足以見得其對多平台的支持。
1、libjpeg庫在安卓源碼路徑為/external/jpeg,編譯源碼時libjpeg.so就已經生成,我們可以直接拿過來使用。
/out/target/product/generic/system/lib/libjpeg.so
2、可以直接用源碼編譯,這也是本文的重點,請看下一節。
安卓源碼中自帶的jpeg版本很可能不是最新的,我們去www.ijg.org下載最新的源碼,解壓後將所有文件放到jni目錄中,准備用ndk編譯。
1、新建config.sh,將ndk中的交叉編譯工具加入其中,內容如下:
NDK=/opt/ndk/android-ndk-r10e/
PLATFORM=$NDK/platforms/android-15/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/
CC=$PREBUILT/bin/arm-linux-androideabi-gcc
./configure --prefix=/home/linc/jpeg-9b/jni/dist --host=arm CC="$CC --sysroot=$PLATFORM"
2、執行此腳本
$ sh config.sh
...
checking whether to build shared libraries... no
checking whether to build static libraries... yes
...
config.status: creating Makefile
config.status: creating jconfig.h
首先,它生成了Makefile,我們可以直接使用此Makefile進行編譯;其次,它生成了重要的頭文件,jconfig.h.
遺憾的是,這個Makefile是編譯static庫而不是共享庫的。
此時,我們可以執行構建命令進行編譯:
jni$ make install-libLTLIBRARIES
libtool: install: ranlib /home/linc/jpeg-9b/jni/dist/lib/libjpeg.a
3、Android.mk
使用ndk-build指令編譯,需要手動編寫Android.mk文件,內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES :=jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c \
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
jcomapi.c jcparam.c jcprepct.c jcsample.c jctrans.c jdapimin.c \
jdapistd.c jdarith.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmerge.c jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c \
jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jquant1.c \
jquant2.c jutils.c jmemmgr.c jmemnobs.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays \
-DANDROID -DANDROID_TILE_BASED_DECODE -DENABLE_ANDROID_NULL_CONVERT
LOCAL_MODULE := libjpeg
LOCAL_MODULE_TAGS := optional
# unbundled branch, built against NDK.
LOCAL_SDK_VERSION := 17
include $(BUILD_SHARED_LIBRARY)
其中LOCAL_SRC_FILES後面的源文件可以參考剛剛生成的Makefile。
在jni目錄上一級使用ndk-build編譯即可。
$ ndk-build
[armeabi] Compile arm : jpeg <= jaricom.c
...
[armeabi] Compile arm : jpeg <= jmemnobs.c
[armeabi] SharedLibrary : libjpeg.so
[armeabi] Install : libjpeg.so => libs/armeabi/libjpeg.so
為了快速測試,我們用C編寫一個可執行程序,新建一個jni目錄,將jconfig.h jmorecfg.h jpeglib.h及libjpeg.so拷進來,
新建jpeg_test.c,借鑒網友的生成jpg圖片的例子,如下:
#include
#include
#include
#include
#include
typedef uint8_t BYTE;
#define true 1
#define false 0
#include "jpeglib.h"
int generateJPEG(BYTE* data,int w, int h, const char* outfilename)
{
int nComponent = 3;
struct jpeg_compress_struct jcs;
struct jpeg_error_mgr jem;
jcs.err = jpeg_std_error(&jem);
jpeg_create_compress(&jcs);
FILE* f=fopen(outfilename,"wb");
if (f==NULL)
{
free(data);
return 0;
}
jpeg_stdio_dest(&jcs, f);
jcs.image_width = w;
jcs.image_height = h;
jcs.input_components = nComponent;
if (nComponent==1)
jcs.in_color_space = JCS_GRAYSCALE;
else
jcs.in_color_space = JCS_RGB;
jpeg_set_defaults(&jcs);
jpeg_set_quality (&jcs, 60, true);
jpeg_start_compress(&jcs, TRUE);
JSAMPROW row_pointer[1];
int row_stride;
row_stride = jcs.image_width*nComponent;
while (jcs.next_scanline < jcs.image_height) {
row_pointer[0] = & data[jcs.next_scanline*row_stride];
jpeg_write_scanlines(&jcs, row_pointer, 1);
}
jpeg_finish_compress(&jcs);
jpeg_destroy_compress(&jcs);
fclose(f);
return 1;
}
BYTE* generateRGB24Data()
{
struct {
BYTE r;
BYTE g;
BYTE b;
} pRGB[100][199];
memset( pRGB, 0, sizeof(pRGB) );
int i=0, j=0;
for( i=50;i<70;i++ ){
for( j=70;j<140;j++ ){
pRGB[i][j].b = 0xff;
}
}
for( i=0;i<10;i++ ){
for( j=0;j<199;j++ ){
pRGB[i][j].r = 0xff;
}
}
BYTE* ret = (BYTE*)malloc(sizeof(BYTE)*100*199*3);
memcpy(ret, (BYTE*)pRGB, sizeof(pRGB));
return ret;
}
int main(void)
{
BYTE* data = generateRGB24Data();
generateJPEG(data,199, 100, "/sdcard/test.jpg");
free(data);
return 0;
}
新建Android.mk,生成可執行文件:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= jpeg_test.c
LOCAL_MODULE:= jtest
LOCAL_LDLIBS :=-llog
LOCAL_LDLIBS += $(LOCAL_PATH)/libjpeg.so
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := debug
include $(BUILD_EXECUTABLE)
執行ndk-build編譯,將jtest和libjpeg.so push到安卓設備的/data/data下(需要有root權限),
/data/data # ./jtest
執行後會在sdcard下生成一個test.jpg.
大功告成後,下一步就將測試其App中在C/C++層將視頻流直接保存成圖片。
借著libjpeg.so,我將測試JNA調用其功能。
敬請期待。
Service概念及用途A service is an application component that can perform long-running opera
今天我們終於可以把這個項目給結束掉啦,有了前幾天的准備,相信最後一天還是比較輕松的,國際慣例: 最後要完成的就是我們的主要功能--拼圖界面。package com.x
本文實例講述了使用SAX來解析XML。通常來說在Android裡面可以使用SAX和DOM,DOM需要把整個XML文件讀入內存再解析,比較消耗內存,而SAX是基於事件驅動的
2013年Google I/O大會上推出了一個新的網絡通信框架——Volley。Volley可是說是把AsyncHttpClient和Univer