Androidアプリ開発 -画像処理をC言語で高速化-

公開日: : 最終更新日:2014/04/20 Android, IT


 画像を扱う際の問題(1):計算処理の遅さ

前回、セピア画像にする方法を書きました。
Androidアプリ開発 -画像を加工してセピア色にしてみる- | PPl@ce

画像を扱う際の問題点の1つに、計算処理の遅さがあります。
前回の計算式レベルでは実時間に処理出来ますが、さらに複雑になってくるとJavaでは厳しいです。
その問題を解消するために、C言語で高速化してみたので、そのお話を以下にまとめておきます。
※もちろん、Javaがなんでもかんでも遅いわけではありません。

他に、メモリー問題もありますが、それはまた別の話。
そして今、私が苦労している話・・(ヘルプミー)。

 JNIを使ってC言語利用

まずは、JNI(Java Native Interface)を使うための流れ。

 (1)まず、Android NDKをダウンロードします。

Windows版を解凍すると以下の様な感じです。

 (2)Androidのプロジェクトにjniフォルダーを用意

 (3)jniフォルダーにAndroid.mkファイルを作成

記述例は以下のような感じ。
※NDK内のサンプルソースを参考にすると良い。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := filter
LOCAL_SRC_FILES := filter.c
LOCAL_LDLIBS    := -lm -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)

 (4)jniフォルダーにC言語ファイルを作成

C言語内の関数は以下のような感じ。
※全体像は、NDK内のサンプルソースを参考にすると良い。

JNIEXPORT void JNICALL Java_com_sample_filter_filter1(JNIEnv * env, jobject  obj,  jintArray src, jint width, jint height)
{
  int i, totalPixel;
  jint* arr  =(*env)->GetIntArrayElements(env,src,0);
  totalPixel = width * height;
 for(i=0; i< totalPixel; i++) {
    int alpha = (arr[i] & 0xFF000000) >> 24;
    int red   = (arr[i] & 0x00FF0000) >> 16;
    int green = (arr[i] & 0x0000FF00) >> 8;
    int blue  = (arr[i] & 0x000000FF);
    //ここに計算処理を色々と書く。
    arr[i] = (alpha << 24) | (red << 16) | (green << 8)| blue;
 }
 (*env)->ReleaseIntArrayElements(env, src, arr, 0);
}

JNI関数の命名規則があるため、「Java_<完全修飾クラス名>_<関数名>」のような形になります。
最初の2つの引数は決まっていてJNI環境へのポインターと呼び出し側クラス・オブジェクト・インスタンスへのポインターになります。
それ以降の値が、計算をするために渡す値になります。

 (5)作成したC言語のファイルをコンパイル

作成したC言語に対して以下のコマンドを呼んでコンパイルします。

  • ndk-build

※ndk-buildは、ダウンロードしたフォルダ内にあります。

あとは、Java側から作成したC言語を呼び出すだけです。
現時点での、フォルダ構成は以下のとおりです。

 おまけ

JNI周りをいじる際に参考になるのは、Android NDKをダウンロードした際にあったサンプルコードです。
これを実際に触って、アプリに入れてみたり、ソースを改良してみたりするとわかりやすいと思います。

 Java側から呼び出し

 ライブラリ呼び出し

まず、ライブラリを呼び出します。

    /* load our native library */
    static {
        System.loadLibrary("filter");
    }

 クラスを用意

ここで、先程作成したfilter1を宣言します。

class ImgFilter{
    private int[] pixcels;
    private int width, height;
    private static native void filter1(int[] pixcels,int width, int height); //宣言
    public ImgFilter(int[] pixcels, int width, int height) {
        this.pixcels = pixcels;
        this.width = width;
        this.height = height;
    }
    /**
     * filter1
     */
    public void filter1()
    {
        filter1(this.pixcels, this.width, this.height);
    }
}

上記のようにクラスにしなくて、filter1だけ以下のように宣言して、利用しても問題ないです。

public static native void filter1(int[] pixcels,int width, int height);

 呼び出し

あとは呼び出したい箇所で、上記のクラスを呼ぶだけです。
以下のような感じです。

 int width = image.getWidth();
 int height = image.getHeight();
 int pixels[] = new int[width * height];
 image.getPixels(pixels, 0, width, 0, 0, width, height);
 ImgFilter ifilter = new ImgFilter(pixels, width, height);
 ifilter.filter1();
 Bitmap bmp = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);
 imgView.setImageBitmap(bmp);

 まとめ

C言語を使うと、Javaに比べてかなり高速になります。
ただし、どこで扱うかはどの処理が遅いかをちゃんと計測してから使うのが良いかと思います。
今回のような画像処理のようなものに関しては、メリットがでかいです。

色々やり過ぎると今度はメモリー問題が面倒だったりしますが・・。

 参考

広告

関連記事

no image

iPhoneアプリ開発 -WebViewで表示しているページで特定のリンククリック時の動作を変える-

* やりたいこと UIWebViewでWebページを表示し、特定のリンクをクリックした際には別処理を

記事を読む

sample1

jQuery Mobile1.2のCollapsible Listsを試してみた -画像のカスタマイズについて-

8月1日にjQuery Mobile1.2 Alphaが出ました。 まだAlphaなので自

記事を読む

スクリーンショット 2012-10-20 14.26.24

iPhoneアプリ開発 −UITabControllerの利用−

* やりたいこと 上にあるように下部にあるタブをタッチしたら別のページを呼び出す。 * 

記事を読む

no image

Selenium2.0でUIテスト(2) -Rubyでやってみよう-

前回は、Selenium + PHPを試しました。 今後はRubyでやってみようということでSele

記事を読む

no image

iPhoneアプリ開発 -同じ画像を2度以上画像処理した際に起こるエラーの対処-

* 起きた現象 (1) UIImageのデータを元にピクセルの値を色々といじって画像処理。 (2)

記事を読む

no image

CakePHP1.3でテストコード(2) -フィクスチャをいじってみる(テストデータの動的登録)-

cakePHP1.3でのSimpleTestを使ったテストケースの第2回目。 今回は、動的にテストデ

記事を読む

no image

アプリのためにFacebookページ作成 -現時点で注意すべき点-

* 前回 会社のメルアドでFacebookページを作成する方法を載せました。 * Faceboo

記事を読む

Selenium2.0でUIテスト(1) -まずはPHPでやってみる-

久しぶりにSeleniumを触ってみました。 Selenium2.0から色々と変わったみたいで少々

記事を読む

no image

Twitterでサービスにログイン -ソーシャルログイン-

* やりたいこと -自身のWebサービスにTwitterIDでログイン(ソーシャルログイン)したい。

記事を読む

no image

Objective-cで悩んでいたこと −アクセサのことについて−

* 疑問 以前書いたiPhoneアプリを開発していて(Objective-Cを触っていて)疑問に思

記事を読む

広告

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

広告

no image
[感想] Effective Objective-C 2.0 ☆☆☆☆★(4.5)

* 構成 - 第1章 Objective-Cに慣れる -

no image
[感想] iOSアプリテスト自動化入門 ☆☆☆(3.0)

* 構成 - Chapter 1 テスト自動化への取り組み

DeployGateを試してみた(iOS編) -DeployGateがiOSに対応-

今までのDeployGate - -[http://pplace.

iPhone/iPadアプリを開発するためにやったこと

今までに、iPhoneを3本ほどリリース((リリースしたアプリは全て1

no image
ターミナルでgitのコマンドを補完したりブランチ名を表示する – macでgitを便利に使うために –

* やりたいこと macのターミナルでgitをいじっていると -今の

→もっと見る

PAGE TOP ↑