我想在我的Android照片编辑器应用程序中添加模糊功能。到目前为止,我已经在Cpp
中编写了以下代码,以提高速度和效率。
class JniBitmap
{
public:
uint32_t* _storedBitmapPixels;
AndroidBitmapInfo _bitmapInfo;
JniBitmap()
{
_storedBitmapPixels = NULL;
}
};
JNIEXPORT void JNICALL Java_com_myapp_utils_NativeBitmapOperations_jniBlurBitmap(JNIEnv * env, jobject obj, jobject handle, uint32_t radius)
{
JniBitmap* jniBitmap = (JniBitmap*) env->GetDirectBufferAddress(handle);
if (jniBitmap->_storedBitmapPixels == NULL) return;
uint32_t width = jniBitmap->_bitmapInfo.width;
uint32_t height = jniBitmap->_bitmapInfo.height;
uint32_t* previousData = jniBitmap->_storedBitmapPixels;
uint32_t* newBitmapPixels = new uint32_t[width * height];
// Array to hold totalRGB
uint8_t totalRGB[3];
uint8_t Pixel_col[3];
uint32_t Pixel_col;
int x, y, kx, ky;
uint8_t tmp;
for (y=0; y<height; y++)
{
for (x=0; x<width; x++)
{
// Colour value RGB
totalRGB[0] = 0.0;
totalRGB[1] = 0.0;
totalRGB[2] = 0.0;
for (ky=-radius; ky<=radius; ky++)
{
for (kx=-radius; kx<=radius; kx++)
{
// Each pixel position
pPixel_col = previousData[(y + ky) * width + x + kx];
totalRBG[0] += (Pixel_col & 0xFF0000) >> 16;
totalRBG[1] += (Pixel_col & 0x00FF00) >> 8;
totalRBG[2] += Pixel_col & 0x0000FF;
}
}
tmp = (radius * 2 + 1) * (radius * 2 + 1);
totalRGB[0] += tmp;
totalRGB[1] += tmp;
totalRGB[2] += tmp;
pPixel_col = totalRGB[0] << 16 + totalRGB[1] << 8 + totalRGB[2];
newBitmapPixels[y * width + x] = pPixel_col;
}
}
delete[] previousData;
jniBitmap->_storedBitmapPixels = newBitmapPixels;
}
我已经成功地编译了它,并发布了最新的Android NDK
版本。
在我的Android应用程序中,我得到了这个Java
代码来调用本机方法:
private ByteBuffer handler = null;
static
{
System.loadLibrary("JniBitmapOperationsLibrary");
}
private native void jniBlurBitmap(ByteBuffer handler, final int radius);
public void blurBitmap(final int radius)
{
if (handler == null) return;
jniBlurBitmap(handler, radius);
}
当我尝试从我的应用程序调用它时,它会给出一个空白图片。我做错什么了吗?
附言:我在JNI
文件中也有一个裁剪和缩放方法,它们工作得很好。这可能是我的Blur algorithm
的问题。
最后,我找到了最快的方法。起初,我制作了一个JNI脚本,但Android支持V8的方式显然更快(大约10倍)。
-
添加库AND目录
SDK/build-tools/android-4.4.2/renderscript/lib/
中的.so
文件。将renderscript-v8.jar
复制到您的libs
文件夹,将packaged
内容复制到jni
文件夹。 -
使用此代码
public static Bitmap getBlurredBitmap(Context context, Bitmap bm, int radius) { if (bm == null) return null; if (radius < 1) radius = 1; if (radius > 25) radius = 25; Bitmap outputBitmap = Bitmap.createBitmap(bm); RenderScript rs = RenderScript.create(context); ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); Allocation tmpIn = Allocation.createFromBitmap(rs, bm); Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); theIntrinsic.setRadius(radius); theIntrinsic.setInput(tmpIn); theIntrinsic.forEach(tmpOut); tmpOut.copyTo(outputBitmap); return outputBitmap; }