如何在Android开发中使用JNI将位图从Java传递到C++
How to pass a bitmap from Java to C++ with JNI in Android Development?
我想使用用于Android开发的JNI将位图从Android传递到C++。
在Java中,我调用这个函数将位图从Java发送到C++:
public native int sendMyBitmap(Bitmap bitmap);
在JNI中,我是这样做的:
JNIEXPORT void JNICALL sendMyBitmap(JNIEnv * env,
jobject obj, jobject bitmap)
{
AndroidBitmapInfo androidBitmapInfo ;
void* pixels;
AndroidBitmap_getInfo(env, bitmap, &androidBitmapInfo);
AndroidBitmap_lockPixels(env, bitmap, &pixels);
unsigned char* pixelsChar = (unsigned char*) pixels;
saveImage(pixelsChar);
}
void saveImage(unsigned char* img)
{
FILE *f;
int w = 640, h = 480;
int filesize = 54 + 3*w*h; //w is your image width, h is image height, both int
unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};
unsigned char bmppad[3] = {0,0,0};
bmpfileheader[ 2] = (unsigned char)(filesize );
bmpfileheader[ 3] = (unsigned char)(filesize>> 8);
bmpfileheader[ 4] = (unsigned char)(filesize>>16);
bmpfileheader[ 5] = (unsigned char)(filesize>>24);
bmpinfoheader[ 4] = (unsigned char)( w );
bmpinfoheader[ 5] = (unsigned char)( w>> 8);
bmpinfoheader[ 6] = (unsigned char)( w>>16);
bmpinfoheader[ 7] = (unsigned char)( w>>24);
bmpinfoheader[ 8] = (unsigned char)( h );
bmpinfoheader[ 9] = (unsigned char)( h>> 8);
bmpinfoheader[10] = (unsigned char)( h>>16);
bmpinfoheader[11] = (unsigned char)( h>>24);
f = fopen("/storage/test.png","wb");
fwrite(bmpfileheader,1,14,f);
fwrite(bmpinfoheader,1,40,f);
for(int i=0; i<h; i++)
{
fwrite(img+(w*(h-i-1)*3),3,w,f);
fwrite(bmppad,1,(4-(w*3)%4)%4,f);
}
fflush(f);
fclose(f);
}
在C++JNI中保存位图后,Java和C++中的位图不同。我正在努力找出问题出在哪里,以及如何才能找到问题。
此行:
fwrite(img + (w * (h - i - 1)*3), 3, w, f);
您假设输入BITMAP每个像素有24个比特(3个字节)。但在android中没有这样的像素格式。
您还假设宽度正好是640像素,高度正好是480像素。在您的情况下,这可能是事实,但您应该阅读这些信息,而不是对值进行硬编码。
所有这些值都是由函数CCD_ 1提供的。你为什么不使用它们?只需检查结构AndroidBitmapInfo
:
typedef struct {
uint32_t width;
uint32_t height;
uint32_t stride;
int32_t format;
uint32_t flags; // 0 for now
} AndroidBitmapInfo;
您可以直接读取位图的尺寸。此外,您应该检查参数format
,它可以是以下值之一:
enum AndroidBitmapFormat {
ANDROID_BITMAP_FORMAT_NONE = 0,
ANDROID_BITMAP_FORMAT_RGBA_8888 = 1,
ANDROID_BITMAP_FORMAT_RGB_565 = 4,
ANDROID_BITMAP_FORMAT_RGBA_4444 = 7,
ANDROID_BITMAP_FORMAT_A_8 = 8,
};
你看到了吗?没有RGB_888
格式。您应该确保从Java co C++以RGBA_8888
像素格式发送位图,并相应地修改算法。我认为将输出像素格式更改为32位(而不是24位)会更容易。
相关文章:
- C / C++ 移位/偏移/向左或向右移动位图?
- 如何在快板的屏幕中显示子位图的绘制?
- CreateDIBSection为同一图像返回不一致的位图位值
- C++ 位图中的 ttc 字体
- 使用 GDI+ 旋转位图,然后转换为 HDC
- 难以从 CImageList 设置菜单项位图
- 如何将位图拉伸到父面板(wxWidgets 自定义)
- 如何使用 freetype2 访问单色位图中的像素状态
- 将位图 (bmp) 转换为具有透明度的 png (Windows c++)
- 安卓工作室 |CPP 文件错误错误: 位图库中对"AndroidBitmap_unlockPixels"的未定义引用
- 位图到垫子/2D 数组
- Gdiplus位图没有Alpha通道
- 如何从路径字符串加载Gdiplus::位图
- 在C++中使用Gdiplus创建透明位图
- 用C++压缩内存中的位图
- C++gdi::内存中的位图到PNG图像
- JNI:RGB565位图到灰度 - 如何将JNI更改的数据传递回Java
- 如何在 NDK 中修改 Android 位图,以便我可以在 Java 端使用它
- 如何在Android开发中使用JNI将位图从Java传递到C++
- 如何将cv::MAT字节数组从c++发送到Java中的位图