Android 使用ndk的位图操作
Android bitmap operations using ndk
目前我正在开发一个涉及图像处理的 Android 应用程序。经过一些研究,我发现最好使用 Android NDK 进行位图操作以获得良好的性能。所以,我找到了一些像这样的基本示例:
static void myFunction(AndroidBitmapInfo* info, void* pixels){
int xx, yy, red, green, blue;
uint32_t* line;
for(yy = 0; yy < info->height; yy++){
line = (uint32_t*)pixels;
for(xx =0; xx < info->width; xx++){
//extract the RGB values from the pixel
blue = (int) ((line[xx] & 0x00FF0000) >> 16);
green = (int)((line[xx] & 0x0000FF00) >> 8);
red = (int) (line[xx] & 0x00000FF );
//change the RGB values
// set the new pixel back in
line[xx] =
((blue << 16) & 0x00FF0000) |
((green << 8) & 0x0000FF00) |
(red & 0x000000FF);
}
pixels = (char*)pixels + info->stride;
}
}
我使用了这段代码,它对基本操作非常有效,但我想做一个更复杂的代码,比如滤镜,我需要从当前像素访问上面和下面的像素。更具体地说,我给你举个例子:对于膨胀和腐蚀操作,我们移动像素,我们验证像素是否来自西北、北部、东北、西部、东部、西南、南部和东南(对于8个邻居结构元素)是对象像素。我需要知道的是如何使用上面的代码访问南北像素的值。
我对使用C(指针等)的图像处理不是很熟悉。
谢谢!
我稍微编辑了你的函数,基本上是为了获取数组中的像素位置,公式为:
位置=y*宽度+x
static void myFunction(AndroidBitmapInfo* info, void* pixels){
int xx, yy, red, green, blue;
uint32_t* px = pixels;
for(yy = 0; yy < info->height; yy++){
for(xx =0; xx < info->width; xx++){
int position = yy*info->width+xx;//this formula gives you the address of pixel with coordinates (xx; yy) in 'px'
//extract the RGB values from the pixel
blue = (int) ((line[position] & 0x00FF0000) >> 16);
green = (int)((line[position] & 0x0000FF00) >> 8);
red = (int) (line[position] & 0x00000FF );
//change the RGB values
// set the new pixel back in
line[position] =
((blue << 16) & 0x00FF0000) |
((green << 8) & 0x0000FF00) |
(red & 0x000000FF);
//so the position of the south pixel is (yy+1)*info->width+xx
//and the one of the north is (yy-1)*info->width+xx
//the left yy*info->width+xx-1
//the right yy*info->width+xx+1
}
}
假设您想要 read/edit 一个坐标为 x,y
的像素
您必须检查 0 <= y < height 和 0 <= x < width ,否则您可能会访问不存在的像素,并且会出现内存访问错误
目前我正在开发一个涉及图像处理的 Android 应用程序。经过一些研究,我发现最好使用 Android NDK 进行位图操作以获得良好的性能。所以,我找到了一些像这样的基本示例:
static void myFunction(AndroidBitmapInfo* info, void* pixels){
int xx, yy, red, green, blue;
uint32_t* line;
for(yy = 0; yy < info->height; yy++){
line = (uint32_t*)pixels;
for(xx =0; xx < info->width; xx++){
//extract the RGB values from the pixel
blue = (int) ((line[xx] & 0x00FF0000) >> 16);
green = (int)((line[xx] & 0x0000FF00) >> 8);
red = (int) (line[xx] & 0x00000FF );
//change the RGB values
// set the new pixel back in
line[xx] =
((blue << 16) & 0x00FF0000) |
((green << 8) & 0x0000FF00) |
(red & 0x000000FF);
}
pixels = (char*)pixels + info->stride;
}
}
我使用了这段代码,它对基本操作非常有效,但我想做一个更复杂的代码,比如滤镜,我需要从当前像素访问上面和下面的像素。更具体地说,我给你举个例子:对于膨胀和腐蚀操作,我们移动像素,我们验证像素是否来自西北、北部、东北、西部、东部、西南、南部和东南(对于8个邻居结构元素)是对象像素。我需要知道的是如何使用上面的代码访问南北像素的值。 我对使用C(指针等)的图像处理不是很熟悉。
谢谢!
我稍微编辑了你的函数,基本上是为了获取数组中的像素位置,公式为:
位置=y*宽度+x
static void myFunction(AndroidBitmapInfo* info, void* pixels){
int xx, yy, red, green, blue;
uint32_t* px = pixels;
for(yy = 0; yy < info->height; yy++){
for(xx =0; xx < info->width; xx++){
int position = yy*info->width+xx;//this formula gives you the address of pixel with coordinates (xx; yy) in 'px'
//extract the RGB values from the pixel
blue = (int) ((line[position] & 0x00FF0000) >> 16);
green = (int)((line[position] & 0x0000FF00) >> 8);
red = (int) (line[position] & 0x00000FF );
//change the RGB values
// set the new pixel back in
line[position] =
((blue << 16) & 0x00FF0000) |
((green << 8) & 0x0000FF00) |
(red & 0x000000FF);
//so the position of the south pixel is (yy+1)*info->width+xx
//and the one of the north is (yy-1)*info->width+xx
//the left yy*info->width+xx-1
//the right yy*info->width+xx+1
}
}
假设您想要 read/edit 一个坐标为 x,y
的像素您必须检查 0 <= y < height 和 0 <= x < width ,否则您可能会访问不存在的像素,并且会出现内存访问错误