英文:
How to iterate through pixels in a more efficient way?
问题
以下是您提供的内容的翻译部分:
我正在获取一张图像并将其转换为位图。为了检查像素的颜色是否介于两个值之间,我遍历给定位图的每个像素。我创建一个新的位图,如果像素在这些值之间,就改变像素并在新的位图上设置Pixel()
;如果像素不在这些值之间,就保持像素原样,并且也在新的位图上进行设置。我将位图的配置从ARGB-8888减少到了RGB_565,但仍然非常慢,并在调试中显示“应用程序可能在其主线程上做了太多的工作”。
是否有更好的方法来做这个,并让应用程序运行更快?
width = bitmap.getWidth();
heigth = bitmap.getHeight();
Bitmap newBitmap = Bitmap.createBitmap(width, heigth, Bitmap.Config.RGB_565);
for(int x = 0; x < width; x++){
for(int y = 0; y < heigth; y++){
int pixel = bitmap.getPixel(x,y);
float[] pixelHue = getHsv(pixel);
if(pixelHue[0] > 170 && pixelHue[0] < 250 ){
//改变像素
pixelHue[0] = pixelHue[0] - 17;
int newColor = setRgb(pixelHue);
newBitmap.setPixel(x, y, newColor);
}
else{
//保持像素原样
newBitmap.setPixel(x, y, pixel);
}
}
}
return newBitmap;
}
private float[] getHsv (int pixel){
int a = Color.alpha(pixel);
int r = Color.red(pixel);
int g = Color.green(pixel);
int b = Color.blue(pixel);
float[] hsv = new float[3];
Color.RGBToHSV(r, g, b, hsv);
return hsv;
}
private int setRgb (float[] hsv){
int rgb;
rgb = Color.HSVToColor(hsv);
return rgb;
}
英文:
I'm getting an Image and convert it into a Bitmap. To check if the color of a pixel is between two values, I iterate through every single pixel of the given Bitmap. I create a new Bitmap, change the pixel if it is between these values and set.Pixel() on the new Bitmap, or leave the Pixel as it is and set it also on the new Bitmap. I reduced the Bitmap.Config from ARGB-8888 to RGB_565 but it is still unbeleavable slow and shows in debug "The application may be doing too much work on its main thread."
Is there a better way to do that and make the app faster?
<!-- language: java -->
width = bitmap.getWidth();
heigth = bitmap.getHeight();
Bitmap newBitmap = Bitmap.createBitmap(width, heigth, Bitmap.Config.RGB_565);
for(int x = 0; x < width; x++){
for(int y = 0; y < heigth; y++){
int pixel = bitmap.getPixel(x,y);
float[] pixelHue = getHsv(pixel);
if(pixelHue[0] > 170 && pixelHue[0] < 250 ){
//Change the Pixel
pixelHue[0] = pixelHue[0] - 17;
int newColor = setRgb(pixelHue);
newBitmap.setPixel(x, y, newColor);
}
else{
//leave the Pixel as it is
newBitmap.setPixel(x, y, pixel);
}
}
}
return newBitmap;
}
private float[] getHsv (int pixel){
int a = Color.alpha(pixel);
int r = Color.red(pixel);
int g = Color.green(pixel);
int b = Color.blue(pixel);
float[] hsv = new float[3];
Color.RGBToHSV(r, g, b, hsv);
return hsv;
}
private int setRgb (float[] hsv){
int rgb;
rgb = Color.HSVToColor(hsv);
return rgb;
}
答案1
得分: 0
> 但是我需要检查像素颜色的色调值,以确定颜色是否在我的范围内。
正确,但您不需要每次都将像素转换为HSV值。您可以进行一次转换,然后存储结果。
因此,您的代码的基本结构可能如下:
HashMap<Integer, Integer> pixels = new HashMap<Integer, Integer>(); // 您的类的实例变量
for (…) {
for (…) {
int pixel = bitmap.getPixel(x, y);
int pixelHue = getPixelHue(pixel);
newBitmap.setPixel(x, y, pixelHue);
}
}
…
private int getPixelHue(int pixel) {
Integer pixelHue = pixels.get(pixel);
if (pixelHue == null) // 您尚未尝试转换此像素
{
float[] hsv = getHsv(pixel);
if (hsv[0] > 170 && hsv[0] < 250) {
// 更改hsv颜色的色调值
hsv[0] = hsv[0] - 17;
pixelHue = setRgb(hsv); // 转换完成
} else {
pixelHue = pixel; // 不需要转换
}
pixels.put(pixel, pixelHue); // 存储结果,这样我们就不需要重新转换
}
return pixelHue;
}
因此,HashMap 最初将为空。当您处理唯一颜色的像素时,您将执行HSV转换和必要时的色调转换,并将结果存储在HashMap中。下次处理此像素颜色时,您无需重复转换过程。
英文:
> but I need to check the hue value of a pixels color to indicate, if the color is in my range
Correct, but you don't need to convert the pixel to an HSV value every time. You can do the conversion once and then store the result.
So the basic structure of your code might be something like:
HashMap<Integer, Integer> pixels = new HashMap<Integer, Integer>(); // instance variable of your class
for(…)
{
for (…)
{
int pixel = bitmap.getPixel(x,y)
int pixelHue = getPixelHue( pixel );
newBitmap.setPixel(x, y, pixelHue);
}
}
…
private int getPixelHue(int pixel)
{
Integer pixelHue = pixels.get(pixel);
if (pixelHue == null) // you haven't attempted to convert this pixel yet
{
float[] hsv = getHsv(pixel);
if(hsv[0] > 170 && hsv[0] < 250 )
{
// Change the hue value of the hsv color
hsv[0] = hsv[0] - 17;
pixelHue = setRgb(hsv); // conversion done
}
else
{
pixelHue = pixel; // no conversion needed
}
pixels.put(pixel, pixelHue); // store result so we don't need to reconvert
}
return pixelHue;
}
So the HashMap will originally be empty. As you process a pixel of a unique color you will do the HSV conversion and hue conversion, if necessary, and store the result in the HashMap. The next time you process this pixel color you don't need to repeat the conversion process.
专注分享java语言的经验与见解,让所有开发者获益!
评论