无法使用android ndk灰显图像

时间:2012-10-19 12:38:26

标签: android c++ c android-ndk

我是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);


}

代码运行正常,但我得到的输出有所不同,请参阅图片enter image description here

点击GoGray按钮后,它会显示如下图像

enter image description here

谁能告诉我错误在哪里?

2 个答案:

答案 0 :(得分:4)

据我所知,Android位图只能处理每像素32位的图像,因此您必须将灰度结果存储为彩色图像,方法是重复红色,绿色和蓝色通道,将Alpha通道设置为完全不透明。

顺便说一句,如果你分析你的截图,你会发现灰度版的宽度恰好是彩色图像的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;
}

希望这有帮助!

答案 1 :(得分:0)

我无法帮助您使用NDK,但我非常确定您可以使用普通的Android SDK创建灰色图像。