我在 android 中为图像上的水彩效果实现了一些代码,但速度很慢(需要 2 分钟以上)现在我尝试在 JNI 中实现这个以提高击球速度,听到的是我的 java 代码
inPixels 是 Bitmap 的像素。
protected int[] filterPixels( int width, int height, int[] inPixels )
{
int levels = 256;
int index = 0;
int[] rHistogram = new int[levels];
int[] gHistogram = new int[levels];
int[] bHistogram = new int[levels];
int[] rTotal = new int[levels];
int[] gTotal = new int[levels];
int[] bTotal = new int[levels];
int[] outPixels = new int[width * height];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
for (int i = 0; i < levels; i++)
rHistogram[i] = gHistogram[i] = bHistogram[i] = rTotal[i] = gTotal[i] = bTotal[i] = 0;
for (int row = -range; row <= range; row++)
{
int iy = y+row;
int ioffset;
if (0 <= iy && iy < height)
{
ioffset = iy*width;
for (int col = -range; col <= range; col++)
{
int ix = x+col;
if (0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int ri = r*levels/256;
int gi = g*levels/256;
int bi = b*levels/256;
rTotal[ri] += r;
gTotal[gi] += g;
bTotal[bi] += b;
rHistogram[ri]++;
gHistogram[gi]++;
bHistogram[bi]++;
}
}
}
}
int r = 0, g = 0, b = 0;
for (int i = 1; i < levels; i++)
{
if (rHistogram[i] > rHistogram[r])
r = i;
if (gHistogram[i] > gHistogram[g])
g = i;
if (bHistogram[i] > bHistogram[b])
b = i;
}
r = rTotal[r] / rHistogram[r];
g = gTotal[g] / gHistogram[g];
b = bTotal[b] / bHistogram[b];
outPixels[index] = (inPixels[index] & 0xff000000) | ( r << 16 ) | ( g << 8 ) | b;
index++;
}
}
return outPixels;
}
**输出图像**
我尝试将此java
代码转换为c
代码,但我不知道出了什么问题,请听一下代码C
void filterPixels( int width, int height, int inPixels[] )
{
int levels = 256;
int index = 0;
int rHistogram [levels];
int gHistogram [levels];
int bHistogram [levels];
int rTotal [levels];
int gTotal [levels];
int bTotal [levels];
int outPixels [width * height];
//Loop Variables
int y ;
int x ;
int i ;
int row ;
int col ;
int j ;
int range = 5 ;
for ( y = 0; y < height; y++)
{
for ( x = 0; x < width; x++)
{
for ( i = 0; i < levels; i++)
rHistogram[i] = gHistogram[i] = bHistogram[i] = rTotal[i] = gTotal[i] = bTotal[i] = 0;
for ( row = -range; row <= range; row++)
{
int iy = y+row;
int ioffset;
if (0 <= iy && iy < height)
{
ioffset = iy*width;
for ( col = -range; col <= range; col++)
{
int ix = x+col;
if (0 <= ix && ix < width) {
int rgb = inPixels[ioffset+ix];
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int ri = r*levels/256;
int gi = g*levels/256;
int bi = b*levels/256;
rTotal[ri] += r;
gTotal[gi] += g;
bTotal[bi] += b;
rHistogram[ri]++;
gHistogram[gi]++;
bHistogram[bi]++;
}
}
}
}
int r = 0, g = 0, b = 0;
for ( j = 1; j < levels; j++)
{
if (rHistogram[j] > rHistogram[r])
r = j;
if (gHistogram[j] > gHistogram[g])
g = j;
if (bHistogram[j] > bHistogram[b])
b = j;
}
r = rTotal[r] / rHistogram[r];
g = gTotal[g] / gHistogram[g];
b = bTotal[b] / bHistogram[b];
outPixels[index] = (inPixels[index] & 0xff000000) | ( r << 16 ) | ( g << 8 ) | b;
index++;
}
}
}
java
我检查代码和代码的像素值c
是否相同(对于相同的图像)
从我的 android 活动调用本机函数的代码。
int[] pix = new int[oraginal.getWidth() * oraginal.getHeight()];
Bitmap bitmap = oraginal.copy(oraginal.getConfig(), true);
bitmap.getPixels(pix, 0, bitmap.getWidth(), 0, 0,bitmap.getWidth(), bitmap.getHeight());
filterPixelsJNI(bitmap.getWidth(), bitmap.getHeight(), pix);
bitmap.setPixels(pix, 0, bitmap.getWidth(), 0, 0,bitmap.getWidth(), bitmap.getHeight());
myView.setImageBitmap(bitmap);
这是我第一次尝试 JNI,所以请帮助我。
更新
public native void filterPixelsJNI( int width, int height, int inPixels[] );
JNI
JNIEXPORT void JNICALL Java_com_testndk_HelloWorldActivity_filterPixelsJNI (JNIEnv * env, jobject obj , jint width,jint height,jint inPixels[]){
filterPixels( width, height, inPixels);
}
filterPixels 方法是从 c 代码调用的。