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アプリ開発 −iOS6からの「写真」へのアクセス問題−

写真を扱うアプリを開発している際に問題になったこと。 ※結構前の話を今更まとめてみる。 * 写真へ

記事を読む

Jenkins + iPhoneアプリ(3) -ipaファイルをTestFlightにアップロード-

* これまで - -[http://pplace.jp/2013/01/1192/:title=

記事を読む

no image

研究室での進捗報告の方法について、ふと思ったこと

* 以下に加筆・修正して移動しました。

記事を読む

Jenkins + DeployGate(1) -DeployGateでAndroidアプリ開発-

TestFlight for Androidが発表されて1ヶ月ぐらいたちますが、音沙汰がありません。

記事を読む

no image

WordPressプラグイン「SyntaxHighlighter Evolved」が動かない!?

* 起きたこと ある時から、本ブログのコードの部分が「SyntaxHighlighter」で表示され

記事を読む

no image

TwitterAPI 1.1対応で困ったこと −フォロー・フォロワー一覧取得−

  TwitterのAPI1.1に2013年の3月15日までには対応しないといけません。

記事を読む

no image

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

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

記事を読む

no image

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

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

記事を読む

mixisample

iPhoneアプリ開発 -mixiSDKを使ってmixi連携をしてみる(1)-

* やりたいこと iPhoneアプリでmixiと連携し、mixiボイスなどに文字を投稿する。 ※

記事を読む

no image

Facebookがちょっとコワイ vol.2 -本当にあなたはあなたなの?-

以下のブログを読んで、さらにコワイと思ったFacebook。 あなたが登録している「友

記事を読む

広告

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 ↑