在 android 中更快地获得 RGB
get RGB faster in android
以下是我获取 RGB 颜色并在位图(另一个位图)中的颜色为绿色时更改临时(位图)颜色的方法。但是性能很差,用了大约 20 秒或更长时间。我有什么方法可以改进它吗?非常感谢。
//get the green color of each pixel
color = new int[bitmap.getWidth()][bitmap.getHeight()];
for (int x = 0; x < bitmap.getWidth(); x++) {
for (int y = 0; y < bitmap.getHeight(); y++) {
color[x][y] = temp.getPixel(x, y);
if (bitmap.getPixel(x, y) == Color.GREEN) {
color[x][y] = temp.getPixel(x, y);
float[] hsv = new float[3];
Color.RGBToHSV(Color.red(color[x][y]), Color.green(color[x][y]), Color.blue(color[x][y]), hsv);
hsv[0] = 360;
color[x][y] = Color.HSVToColor(hsv);
}
temp.setPixel(x, y, color[x][y]);
}
}
imageView.setImageBitmap(temp);
更新:
intArray = new int[bitmap.getWidth()*bitmap.getHeight()];
bitmap.getPixels(intArray,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
int[] tempArray = new int[bitmap.getWidth()*bitmap.getHeight()];
temp.getPixels(tempArray,0,temp.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
//get the color of each pixel
color = new int[bitmap.getWidth()][bitmap.getHeight()];
for (int x = 0; x < bitmap.getWidth(); x++) {
for (int y = 0; y < bitmap.getHeight(); y++) {
if (intArray[x + y * bitmap.getWidth()] == Color.BLUE) {
float[] hsv = new float[3];
Color.RGBToHSV(Color.red(tempArray[x + y * bitmap.getWidth()]), Color.green(tempArray[x + y * bitmap.getWidth()]), Color.blue(tempArray[x + y * bitmap.getWidth()]), hsv);
hsv[0] = 360;
tempArray[x + y * bitmap.getWidth()] = Color.HSVToColor(hsv);
}
}
}
temp.setPixels(tempArray,0,temp.getWidth(),0,0,temp.getWidth(),temp.getHeight());
imageView.setImageBitmap(temp);
我想我要做的是确定每个像素的大小。最有可能是 32 位 ARGB。所以你有一个 WxH 多头数组。遍历该数组,如果值是 G = 255 的值,则替换它。我也会忽略 ALPHA 通道
有几种方法可以加快速度。让我们从最简单的开始:
float[] hsv = new float[3];
使用 new
在堆上分配内存,这很慢而且对缓存不友好(并且需要事后释放(取决于语言,这可能是自动的))。您可以(重新)使用本地 float[3] 代替。
color[x][y] = temp.getPixel(x, y);
if (bitmap.getPixel(x, y) == Color.GREEN) {
color[x][y] = temp.getPixel(x, y);
这里不需要做第二个 temp.getPixel()
(这可能会很慢)。数据已经在 color[x][y]
.
color[x][y] = temp.getPixel(x, y);
if (bitmap.getPixel(x, y) == Color.GREEN) {
// ...
}
temp.setPixel(x, y, color[x][y]);
没有变化的像素不需要设置。因此,您可以将 temp.setPixel
移动到 if
块内。实际上 color[x][y] = temp.getPixel(x, y);
也可以进入 if
块(或者只是删除外部的,因为它已经在 if
块内)
color = new int[bitmap.getWidth()][bitmap.getHeight()];
首先,你可能想在这里使用unsigned int
,但实际上你不需要这第三个数组。您可以只使用本地 unsigned int color
变量。
for (int x = 0; x < bitmap.getWidth(); x++) {
for (int y = 0; y < bitmap.getHeight(); y++) {
根据语言的不同,您可能希望颠倒循环的顺序以使缓存更友好(请参阅 this)。最简单的确认方法是对这两个订单进行快速测试。
getPixel()
和 setPixel()
可能会很慢(同样取决于语言)。最好像处理二维数组一样直接处理像素数据。大多数语言都提供了获取指针或访问原始像素数据的功能。
以下是我获取 RGB 颜色并在位图(另一个位图)中的颜色为绿色时更改临时(位图)颜色的方法。但是性能很差,用了大约 20 秒或更长时间。我有什么方法可以改进它吗?非常感谢。
//get the green color of each pixel
color = new int[bitmap.getWidth()][bitmap.getHeight()];
for (int x = 0; x < bitmap.getWidth(); x++) {
for (int y = 0; y < bitmap.getHeight(); y++) {
color[x][y] = temp.getPixel(x, y);
if (bitmap.getPixel(x, y) == Color.GREEN) {
color[x][y] = temp.getPixel(x, y);
float[] hsv = new float[3];
Color.RGBToHSV(Color.red(color[x][y]), Color.green(color[x][y]), Color.blue(color[x][y]), hsv);
hsv[0] = 360;
color[x][y] = Color.HSVToColor(hsv);
}
temp.setPixel(x, y, color[x][y]);
}
}
imageView.setImageBitmap(temp);
更新:
intArray = new int[bitmap.getWidth()*bitmap.getHeight()];
bitmap.getPixels(intArray,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
int[] tempArray = new int[bitmap.getWidth()*bitmap.getHeight()];
temp.getPixels(tempArray,0,temp.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
//get the color of each pixel
color = new int[bitmap.getWidth()][bitmap.getHeight()];
for (int x = 0; x < bitmap.getWidth(); x++) {
for (int y = 0; y < bitmap.getHeight(); y++) {
if (intArray[x + y * bitmap.getWidth()] == Color.BLUE) {
float[] hsv = new float[3];
Color.RGBToHSV(Color.red(tempArray[x + y * bitmap.getWidth()]), Color.green(tempArray[x + y * bitmap.getWidth()]), Color.blue(tempArray[x + y * bitmap.getWidth()]), hsv);
hsv[0] = 360;
tempArray[x + y * bitmap.getWidth()] = Color.HSVToColor(hsv);
}
}
}
temp.setPixels(tempArray,0,temp.getWidth(),0,0,temp.getWidth(),temp.getHeight());
imageView.setImageBitmap(temp);
我想我要做的是确定每个像素的大小。最有可能是 32 位 ARGB。所以你有一个 WxH 多头数组。遍历该数组,如果值是 G = 255 的值,则替换它。我也会忽略 ALPHA 通道
有几种方法可以加快速度。让我们从最简单的开始:
float[] hsv = new float[3];
使用 new
在堆上分配内存,这很慢而且对缓存不友好(并且需要事后释放(取决于语言,这可能是自动的))。您可以(重新)使用本地 float[3] 代替。
color[x][y] = temp.getPixel(x, y);
if (bitmap.getPixel(x, y) == Color.GREEN) {
color[x][y] = temp.getPixel(x, y);
这里不需要做第二个 temp.getPixel()
(这可能会很慢)。数据已经在 color[x][y]
.
color[x][y] = temp.getPixel(x, y);
if (bitmap.getPixel(x, y) == Color.GREEN) {
// ...
}
temp.setPixel(x, y, color[x][y]);
没有变化的像素不需要设置。因此,您可以将 temp.setPixel
移动到 if
块内。实际上 color[x][y] = temp.getPixel(x, y);
也可以进入 if
块(或者只是删除外部的,因为它已经在 if
块内)
color = new int[bitmap.getWidth()][bitmap.getHeight()];
首先,你可能想在这里使用unsigned int
,但实际上你不需要这第三个数组。您可以只使用本地 unsigned int color
变量。
for (int x = 0; x < bitmap.getWidth(); x++) {
for (int y = 0; y < bitmap.getHeight(); y++) {
根据语言的不同,您可能希望颠倒循环的顺序以使缓存更友好(请参阅 this)。最简单的确认方法是对这两个订单进行快速测试。
getPixel()
和 setPixel()
可能会很慢(同样取决于语言)。最好像处理二维数组一样直接处理像素数据。大多数语言都提供了获取指针或访问原始像素数据的功能。