我想使用 JNI 在 Android 中实现卷积矩阵算法。我已尽力这样做,但在使用 JNI 应用卷积后总是得到线条图像。这是 Java 中的卷积算法:
private static final int MATRIX_SIZE = 3;
private static int cap(int color) {
if (color 255)
return 255;
else
return color;
}
public static Bitmap convolute(Bitmap bmp, Matrix mat, float factor, int offset) {
// get matrix values
float [] mxv = new float[MATRIX_SIZE * MATRIX_SIZE];
mat.getValues(mxv);
// cache source pixels
int width = bmp.getWidth();
int height = bmp.getHeight();
int [] scrPxs = new int[width * height];
bmp.getPixels(scrPxs, 0, width, 0, 0, width, height);
// clone source pixels in an array
// here we’ll store results
int [] rtPxs = scrPxs.clone();
int r, g, b;
int rSum, gSum, bSum;
int idx; // current pixel index
int pix; // current pixel
float mv; // current matrix value
for(int x = 0, w = width – MATRIX_SIZE + 1; x < w; ++x) {
for(int y = 0, h = height – MATRIX_SIZE + 1; y < h; ++y) {
idx = (x + 1) + (y + 1) * width;
rSum = gSum = bSum = 0;
for(int mx = 0; mx < MATRIX_SIZE; ++mx) {
for(int my = 0; my < MATRIX_SIZE; ++my) {
pix = scrPxs[(x + mx) + (y + my) * width];
mv = mxv[mx + my * MATRIX_SIZE];
rSum += (Color.red(pix) * mv);
gSum += (Color.green(pix) * mv);
bSum += (Color.blue(pix) * mv);
}
}
r = cap((int)(rSum / factor + offset));
g = cap((int)(gSum / factor + offset));
b = cap((int)(bSum / factor + offset));
// store computed pixel
rtPxs[idx] = Color.argb(Color.alpha(scrPxs[idx]), r, g, b);
}
}
// return bitmap with transformed pixels
return Bitmap.createBitmap(rtPxs, width, height, bmp.getConfig());
}
这是 JNI 中的实现:
extern "C" JNIEXPORT void JNICALL Java_com_example_filtertest_JniLoader_applyconvolution(JNIEnv * env, jobject obj, jobject bitmap)
{
LOGI("Applying convolution to the bitmap...");
AndroidBitmapInfo info;
int ret;
void* pixels;
if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
return;
}
if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
convolute(&info, pixels);
AndroidBitmap_unlockPixels(env, bitmap );
LOGI("Bitmap is blurred successfully...");
}
void convolute(AndroidBitmapInfo* info, void* pixels)
{
int width = info->width;
int height = info->height;
int r, g, b;
int rSum, gSum, bSum , w , h;
int idx; // current pixel index
int pix; // current pixel
float mv; // current matrix value
int factor = 1 , offset = 127;
uint32_t naseeb;
rgba* input = (rgba*) pixels;
rgba p;
uint32_t* line = (uint32_t*)pixels;
w = width - SIZE + 1;
h = height - SIZE + 1;
for(int x = 0; x < w; ++x)
{
for(int y = 0; y < h; ++y)
{
idx = (x + 1) + (y + 1) * width;
rSum = gSum = bSum = 0;
for(int mx = 0; mx < SIZE; ++mx)
{
for(int my = 0; my < SIZE; ++my)
{
naseeb = line[(x + mx) + (y + my) * width];
//extract the RGB values from the pixel
r = (int) ((naseeb & 0x00FF0000) >> 16);
g = (int)((naseeb & 0x0000FF00) >> 8);
b = (int) (naseeb & 0x00000FF );
mv = GaussianBlurConfig1[mx + my * SIZE];
rSum += (r * mv);
gSum += (g * mv);
bSum += (b * mv);
}
}
r = rgb_clamp((int)(rSum / factor + offset));
g = rgb_clamp((int)(gSum / factor + offset));
b = rgb_clamp((int)(bSum / factor + offset));
// set the new pixel back in
line[idx] =
((r << 16) & 0x00FF0000) |
((g << 8) & 0x0000FF00) |
(b & 0x000000FF);
}
}
}
请帮助我。在此先感谢。