I am new to android ndk.I have started learning through the image processing example by
ruckus and by IBM blog. I am trying to graying out an image.
Here is the code i am using
An xml file for the layout shown
<?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>
and the java code is
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);
}
and here is the .c file where i have written the code for gray out logic
/*
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);
}
The code is running fine but output i am getting is different see the pics
after clicking the GoGray button it shows image like this

Can anyone tell me where the mistake is ?
As far as i know, Android bitmaps can only handle 32-bit-per-pixel images, so you have to store the grayscale result as if it where a color image, by repeating the gray value in the red, green and blue channels, setting the alpha channel to fully opaque.
By the way if you analyze your screenshots, you’ll realize that the grayscale version has a width of precisely 1/4 of the color image, which tends to show this is the problem.
Using this code in the C++ part should do the job:
Hope this helps!