作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我是 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 按钮后,它会显示这样的图像
谁能告诉我错误在哪里?
最佳答案
据我所知,Android 位图只能处理每像素 32 位的图像,因此您必须像存储彩色图像一样存储灰度结果,通过在红色、绿色和蓝色 channel ,将 alpha channel 设置为完全不透明。
顺便说一句,如果您分析屏幕截图,您会发现灰度版本的宽度恰好是彩色图像的 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;
}
希望这对您有所帮助!
关于android - 无法使用android ndk使图像变灰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12974467/
经过很长时间的尝试,我仍然找不到解决问题的正确方法。问题是将这个灰度图像分割成 3 种不同的颜色:边界应该是黑色,边界的内部空间应该是白色,所有其他介质应该是黑色。 我尝试了几种不同的方法,包括直接强
这个问题在这里已经有了答案: What is the difference between "./somescript.sh" and ". ./somescript.sh" (4 个答案) 关闭
我是一名优秀的程序员,十分优秀!