安卓JNI镜头模糊



我想在我的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;
    }
    

相关内容

  • 没有找到相关文章

最新更新