![]()
今回はIJGのJPEGライブラリ(libjpeg、jpeglib)をAndroid NDKから利用してJpgファイルを表示する。
まずIndependent JPEG GroupからJPEGライブラリのソースファイルをダウンロードする。「jpegsr8c.zip」というファイルだった。
![]()
EasyProjectGenerator for Androidで雛形となるAndroidプロジェクトを作成する。今回はC++でNativeViewを利用する。
![]()
ダウンロードしたJPEGライブラリのソースファイル一式をAndroidプロジェクトのjniフォルダへ解凍する。
![]()
さらにjniフォルダにあったソースファイルやmakefileを「Test118」というフォルダを作成してその中へ移動する。
include $(call all-subdir-makefiles)
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libjpeg 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 jmemname.c include $(BUILD_STATIC_LIBRARY)
![]()
次にlibjpegの「jpeg-8c」フォルダの中にある「jconfig.txt」ファイルを選択した状態で[F2]キーを押して、ファイル名を「jconfig.h」に変更する。これでJPEGライブラリのビルド準備が整った。
#if(true)
#define LOCAL_LOG
#define LOCAL_LOGD
#endif
#include <jni.h>
#include <android/bitmap.h>
#ifdef LOCAL_LOG
#include <android/log.h>
#endif
/* this function is from Android NDK bitmap-plasma , and modify for green color bug */
static uint16_t make565(int red, int green, int blue)
{
return (uint16_t)( ((red << 8) & 0xf800) |
((green << 3) & 0x07e0) |
((blue >> 3) & 0x001f) );
}
#include <stdio.h>
extern "C"
{
#define XMD_H
#include "../jpeg-8c/jpeglib.h"
#include "../jpeg-8c/jerror.h"
}
static void _JpegError(j_common_ptr cinfo)
{
char pszMessage[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo,pszMessage);
__android_log_print(ANDROID_LOG_INFO,"Test118","error! %s",pszMessage);
}
static int DrawBitmap(AndroidBitmapInfo* pBitmapInfo, void* pPixels,const char* pszJpegFile)
{
int yy;
int nJpegLineBytes; //JPEG1ラインのバイト数
char* lpbtBits;
JSAMPLE* pSample;
FILE* fp;
JSAMPROW buffer[1];
JSAMPLE tmp;
jpeg_decompress_struct cInfo;
jpeg_error_mgr jError;
fp = fopen(pszJpegFile,"rb");
if(fp == NULL)
return 0;
cInfo.err = jpeg_std_error(&jError); //エラーハンドラ設定
jError.error_exit = _JpegError; //エラーハンドラ設定
jpeg_create_decompress(&cInfo); //
jpeg_stdio_src(&cInfo,fp); //読込ファイル設定
jpeg_read_header(&cInfo,TRUE); //ヘッダー読込
jpeg_start_decompress(&cInfo); //デコードスタート
nJpegLineBytes = cInfo.output_width * cInfo.output_components; //JPEG 1ラインのバイト数
pSample = new JSAMPLE[nJpegLineBytes + 10]; // ラインバッファ確保
buffer[0] = pSample;
yy = 0;
while(cInfo.output_scanline < cInfo.output_height)
{
if(yy >= pBitmapInfo->height)
break;
jpeg_read_scanlines(&cInfo,buffer,1); //Jpegを1ライン読み込む
int xx;
int x3;
uint16_t* pLine = (uint16_t*)pPixels;
for(xx = 0, x3 = 0; xx < pBitmapInfo->width && x3 < nJpegLineBytes; xx++, x3 += 3)
{
//JPEGはBGRの順
pLine[xx] = make565(buffer[0][x3 + 0],buffer[0][x3 + 1],buffer[0][x3 + 2]);
}
// go to next line
pPixels = (char*)pPixels + pBitmapInfo->stride;
yy++;
}
delete pSample;
jpeg_finish_decompress(&cInfo); // 読み込み終了処理
jpeg_destroy_decompress(&cInfo);
fclose(fp);
return 1;
}
extern "C"
JNIEXPORT void JNICALL Java_com_Test118_NativeView_RenderBitmap(JNIEnv * env, jobject obj, jobject bitmap)
{
AndroidBitmapInfo info;
void* pixels;
int ret;
if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0)
return;
if (info.format != ANDROID_BITMAP_FORMAT_RGB_565)
return;
if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0)
return;
DrawBitmap(&info,pixels,"/sdcard/test.jpg");
AndroidBitmap_unlockPixels(env, bitmap);
}
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := Test118 LOCAL_SRC_FILES := Test118.cpp LOCAL_LDLIBS := -lz -ljnigraphics LOCAL_STATIC_LIBRARIES += libjpeg LOCAL_IS_SUPPORT_LOG := true ifeq ($(LOCAL_IS_SUPPORT_LOG),true) LOCAL_LDLIBS += -llog endif include $(BUILD_SHARED_LIBRARY)
![]()
これでビルドをかけると、libjpeg.aとそれを利用したバイナリが生成される。
![]()
テスト表示用のjpgファイル「test.jpg」をAndroidエミュレーターのSDカードへと転送する。
![]()
そしてプロジェクトを実行すると、jpgファイルが表示された。
プロジェクトファイルをダウンロード
