tdnki @ ウィキ
FasterDrawing
最終更新:
Bot(ページ名リンク)
-
view
3. 描画の高速化
前回、Canvas#drawBitmap()が意外に遅いことがわかってしまった。
3-1. drawBitmap(Bitmap, float, float, Paint)を使う
このメソッドに、今まではintの配列を渡していたが、Bitmapを渡すオーバーロードを呼んでみたところ、int[]に比べて3倍ほど高速であった。
そこで、描画データはBitmapで持つように修正する。
そこで、描画データはBitmapで持つように修正する。
MainActivity.java
@Override
protected void onResume() {
:
:
// 描画用Bitmap
previewBitmap = Bitmap.createBitmap(previewSize.width, previewSize.height, Bitmap.Config.ARGB_8888);
:
:
}
@Override
protected void onPause() {
super.onPause();
if (camera != null) {
camera.stopPreview();
camera.release();
}
if (previewBitmap != null) {
previewBitmap.recycle();
}
}
3-2. nativeコードでBitmapを扱う
int[]からBitmapを生成する処理もそこそこ重く、描画データをBitmapに変更することで浮くであろうマージンを食い潰してしまう。
幸いnativeからBitmapのピクセルデータに触る方法があるので、Bitmapをそのまま渡し、書き換える形に変更する。
C++がJavaのクラスを意識するのは気持ち悪いが、速度にはかえられない。
C++がJavaのクラスを意識するのは気持ち悪いが、速度にはかえられない。
ComicFinder.hpp
JNIEXPORT bool JNICALL Java_com_example_comicfinder_MainActivity_processImage (JNIEnv *, jobject ,jbyteArray, jobject, jint, jint);
ComicFinder.cpp
#include <stdlib.h>
#include <android/bitmap.h>
#include "ComicFinder.hpp"
JNIEXPORT bool JNICALL Java_com_example_comicfinder_MainActivity_processImage
(JNIEnv *env, jobject me, jbyteArray src, jobject dst, jint width, jint height)
{
int ret;
unsigned char *p_dst;
if ((ret = AndroidBitmap_lockPixels(env, dst, reinterpret_cast<void **>(&p_dst))) < 0) {
return false;
}
unsigned char *p_src = reinterpret_cast<unsigned char *>(env->GetPrimitiveArrayCritical(src, NULL));
if (NULL == p_src) {
AndroidBitmap_unlockPixels(env, dst);
return false;
}
for (int k = 0; k < width*height; k++) {
p_dst[k*4+0] = p_dst[k*4+1] = p_dst[k*4+2] = p_src[k];
p_dst[k*4+3] = 0xff;
}
env->ReleasePrimitiveArrayCritical(src, p_src, 0);
AndroidBitmap_unlockPixels(env, dst);
return true;
}
jnigraphicsをリンクする。
Android.mk
LOCAL_LDLIBS := -ljnigraphics
3-3. まとめ
描画が10msで回るようになった。
ここまでのソース
ComicFinder.zip
添付ファイル