2

私は android ndk を初めて使用します。ruckus と IBM ブログによる画像処理の例を通して学習を始めました。画像をグレーアウトしようとしています。これが私が使用しているコードです

表示されているレイアウトの xml ファイル

<?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"  
  >
    <ImageView
      android:id="@+id/gimageView1"
      android:layout_width="400px"
      android:src="@drawable/wallace"
      android:layout_height="266px"
    />

    <Button
      android:id="@+id/gbutton"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="Go Gray"
    />

    <ImageView
      android:id="@+id/gimageView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
    />
  </LinearLayout>

Javaコードは

package com.example;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class GrayClass extends Activity {
      private ImageView imageView;
      private Bitmap bitmap;
      private Button button;
      private Bitmap original;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.gray);
      original  = BitmapFactory.decodeResource(getResources(), R.drawable.wallace);
      bitmap    = BitmapFactory.decodeResource(getResources(), R.drawable.wallace);
      button    = (Button) findViewById(R.id.gbutton);
      imageView = (ImageView) findViewById(R.id.gimageView2);
      button.setOnClickListener(new OnClickListener() {

      public void onClick(View v) {
            ((ImageView)findViewById(R.id.gimageView1)).setVisibility(View.GONE);
            button.setVisibility(View.GONE);
              GoGray();     
      }

    });

  }

  private void GoGray() {
        Bitmap oBitmap = original.copy(Bitmap.Config.ARGB_8888, true);
        Bitmap gBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

        goGrayWithNative(oBitmap,gBitmap );
        imageView.setImageBitmap(gBitmap);

  }

  public native void goGrayWithNative(Bitmap bmp1, Bitmap bmp2);
}

そして、ここにグレーアウトロジックのコードを書いた.cファイルがあります

/*
convertToGray
Pixel operation
*/
JNIEXPORT void JNICALL Java_com_example_GrayClass_goGrayWithNative(JNIEnv
* env, jobject  obj, jobject bitmapcolor,jobject bitmapgray)
{
    AndroidBitmapInfo  infocolor;
    void*              pixelscolor;
    AndroidBitmapInfo  infogray;
    void*              pixelsgray;
    int                ret;
    int             y;
    int             x;

    if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }

    if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infogray)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }

    if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("Bitmap format is not RGBA_8888 !");
        return;
    }


LOGE("Bitmap format is not RGBA_8888 !====%d==", infocolor.format ) ;




    if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsgray)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }


    // modify pixels with image processing algorithm
    LOGI("unlocking pixels height = %d",infocolor.height);
    for(y=0;y<infocolor.height;y++) {
    LOGI("unlocking pixels height = %d",infocolor.width);
        argb * line = (argb *) pixelscolor;
        uint8_t * grayline = (uint8_t *) pixelsgray;

        for(x=0;x<infocolor.width;x++) {

            grayline[x] = 0.3 * line[x].red + 0.59 * line[x].green + 0.11*line[x].blue;
        }
        pixelscolor = (char *)pixelscolor + infocolor.stride;
        pixelsgray = (char *) pixelsgray + infogray.stride;
    }

    LOGI("unlocking pixels");
    AndroidBitmap_unlockPixels(env, bitmapcolor);
    AndroidBitmap_unlockPixels(env, bitmapgray);


}

コードは正常に実行されていますが、取得している出力が異なります。写真を参照してくださいここに画像の説明を入力

GoGrayボタンをクリックすると、このような画像が表示されます

ここに画像の説明を入力

間違いがどこにあるか誰か教えてもらえますか?

4

2 に答える 2

4

私の知る限り、Android ビットマップはピクセルあたり 32 ビットの画像しか処理できないため、赤、緑、青のチャネルでグレー値を繰り返して、グレースケールの結果をカラー画像のように保存する必要があります。アルファチャンネルを完全に不透明に設定します。

ちなみに、スクリーンショットを分析すると、グレースケール バージョンの幅がカラー イメージのちょうど 1/4 であることがわかります。これは、これが問題であることを示している傾向があります。

C++ 部分でこのコードを使用すると、次のようになります。

// modify pixels with image processing algorithm
LOGI("unlocking pixels height = %d",infocolor.height);
for(y=0;y<infocolor.height;y++) {
LOGI("unlocking pixels height = %d",infocolor.width);
    argb * line = (argb *) pixelscolor;
    argb * grayline = (argb *) pixelsgray;

    for(x=0;x<infocolor.width;x++) {

        uint8_t v = 0.3 * line[x].red + 0.59 * line[x].green + 0.11*line[x].blue;
        grayline[x].red = v;
        grayline[x].green = v;
        grayline[x].blue = v;
        grayline[x].alpha = line[x].alpha
    }
    pixelscolor = (char *)pixelscolor + infocolor.stride;
    pixelsgray = (char *) pixelsgray + infogray.stride;
}

お役に立てれば!

于 2012-10-19T12:49:22.627 に答える
0

NDKについてはお役に立てませんが、通常のAndroidSDKでグレーの画像を作成できると確信しています。

于 2012-10-19T12:49:28.360 に答える