2015-10-18 114 views
2

Android中的getPixels()在上下左右或左右上下读取像素。基本上它是按行或列读取的。如果我想告诉图片中红色值越高,我可以这样做(我认为它是按列读取的)。如何检测位图中的红色像素

 Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); 

     imgTakenPhoto.setImageBitmap(thumbnail); 
     int[] pixels = new int[thumbnail.getHeight()*thumbnail.getWidth()]; 

     thumbnail.getPixels(pixels, 0, thumbnail.getWidth(), 0, 0, thumbnail.getWidth(), thumbnail.getHeight()); 
     Colered[] color = new Colered[pixels.length]; 
     int length = pixels.length; 
     int width = thumbnail.getWidth(); 
     int height = thumbnail.getHeight(); 
     for(int i=0; i<pixels.length;i++){ 
      color[i] = new Colered(getRed(pixels[i]),getBlue(pixels[i]),getGreen(pixels[i])); 
      System.out.print(color[i].red + " "); 
     } 
     int indice=-1; 
     int greatest = -1; 
     for(int i=0;i<length-1;i++){ 
      if(color[i].red> greatest){ 
       greatest = color[i].red; 
       indice = i; 
      } 


     } 

     public static int getRed(int color){ 
    return (color >> 16) & 0xFF; 
    } 
+2

我用c#编写了一个类似于你正在做的事情的程序,我注意到的一件事是红色在图片中很少是红色的,你必须给它一个可能的红色范围,或许使用RGB,其中R大于X且G和B小于Y,例如。 – Eliseo

+0

将位图转换为像素数组,然后遍历它并找到红色像素(如果有的话)! –

+0

'Android中的getPixels()在左上角,左右上下读取像素。基本上它是按行或列** ** NO **读取的。它读取'特定的x,y坐标'。 –

回答

3

您的代码查找“红色”像素,红色值最高的像素。我不认为这实际上是你需要的,但如果我错了,请纠正我。

你也过于复杂的事情。让我们先从一个Bitmap和两个循环:

int redThreshold = 200; // adjust this to your needs 
List<int[]> redPixels = new ArrayList<>(); // redPixels.get(int)[0] = x, redPixels.get(int)[1] = y 
Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); 
for(int x = 0; x < thumbnail.getWidth(); x++) // x is row 
    for(int y = 0; y < thumbnail.getHeight(); y++) // y is col 
     if(Color.red(thumbnail.getPixel(x, y)) > redThreshold) { 
      redPixels.add(new int[]{x, y}); 
      System.out.println(String.format("Pixel at (%d, %d) has a red value exceeding our threshold of %d!", x, y, redThreshold); 
     } 

由于@Eliseo暗示在他的评论中,根据您的实际需要,你可能需要检查其他两个颜色是低于某一阈值,以及,如这将拾取诸如白色的颜色(r = 255,g = 255,b = 255是白色!)。

那么,我们如何寻找视觉冲击?你和我会看到并同意的只是“红色”。那么,让我们确保我们的红色值与绿色或蓝色中的较大值相适应;蓝色和绿色在彼此的范围内,否则我们会变成粉红色和橙色。类似这样的:

int thresholdRatio = 2; 
int threshold = 15; 
List<int[]> redPixels = new ArrayList<>(); 
Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); 
for(int x = 0; x < thumbnail.getWidth(); x++) 
    for(int y = 0; y < thumbnail.getHeight(); y++) { 
     Color color = thumbnail.getPixel(x, y); 
     int r = Color.red(color); 
     int g = Color.green(color); 
     int b = Color.blue(color); 
     if((r > (Math.max(g, b) * thresholdRatio)) && (Math.abs(g - b) < threshold)) { 
      redPixels.add(new int[]{x, y}); 
      System.out.println(String.format("Pixel at (%d, %d) has a red value more than %d times the max(green, blue) value, and the green and blue value are also within %d points!", x, y, thresholdRatio, threshold); 
     } 
    } 

这将捕获非常浅和非常深的红色阴影。如果需要捕捉非常特定的红色阴影,请添加天花板和地板阈值。

想要想象哪些像素被捕获?如果位图是可变的,我们可以。

Random rand = new Random(); 
Color getRandomColor() { 
    int[] rgb = new int[3]; 
    for(int i = 0; i < rgb.length; i++) { 
     rgb[i] = rand.nextInt(256); 
    } 
    return Color.rgb(rgb[0], rgb[1], rgb[2]); 
} 

boolean transformRedPixels(Bitmap bm, List<int[]> redPixels) { 
    for(int[] coords : redPixels) { 
     bm.setPixel(coords[0], coords[1], getRandomColor()); // This will set each pixel caught to a new random color 
    } 
    return bm.isMutable(); 
} 

让我知道这是否适合您的需求。快乐编码:)

相关问题