2012-05-10 2 views

ответ

7

в Java итерации на каждый пиксел и определить цвет

import java.awt.image.BufferedImage; 
import java.io.File; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 
import javax.imageio.ImageIO; 
import javax.imageio.ImageReader; 
import javax.imageio.stream.ImageInputStream; 


public class ImageTester { 


    public static void main(String args[]) throws Exception { 
     File file = new File("C:\\Users\\Andrew\\Desktop\\myImage.gif"); 
     ImageInputStream is = ImageIO.createImageInputStream(file); 
     Iterator iter = ImageIO.getImageReaders(is); 

     if (!iter.hasNext()) 
     { 
      System.out.println("Cannot load the specified file "+ file); 
      System.exit(1); 
     } 
     ImageReader imageReader = (ImageReader)iter.next(); 
     imageReader.setInput(is); 

     BufferedImage image = imageReader.read(0); 

     int height = image.getHeight(); 
     int width = image.getWidth(); 

     Map m = new HashMap(); 
     for(int i=0; i < width ; i++) 
     { 
      for(int j=0; j < height ; j++) 
      { 
       int rgb = image.getRGB(i, j); 
       int[] rgbArr = getRGBArr(rgb);     
       // Filter out grays....     
       if (!isGray(rgbArr)) {     
         Integer counter = (Integer) m.get(rgb); 
         if (counter == null) 
          counter = 0; 
         counter++;         
         m.put(rgb, counter);     
       }     
      } 
     }   
     String colourHex = getMostCommonColour(m); 
     System.out.println(colourHex); 
    } 


    public static String getMostCommonColour(Map map) { 
     List list = new LinkedList(map.entrySet()); 
     Collections.sort(list, new Comparator() { 
       public int compare(Object o1, Object o2) { 
       return ((Comparable) ((Map.Entry) (o1)).getValue()) 
        .compareTo(((Map.Entry) (o2)).getValue()); 
       } 
     });  
     Map.Entry me = (Map.Entry)list.get(list.size()-1); 
     int[] rgb= getRGBArr((Integer)me.getKey()); 
     return Integer.toHexString(rgb[0])+" "+Integer.toHexString(rgb[1])+" "+Integer.toHexString(rgb[2]);   
    }  

    public static int[] getRGBArr(int pixel) { 
     int alpha = (pixel >> 24) & 0xff; 
     int red = (pixel >> 16) & 0xff; 
     int green = (pixel >> 8) & 0xff; 
     int blue = (pixel) & 0xff; 
     return new int[]{red,green,blue}; 

    } 
    public static boolean isGray(int[] rgbArr) { 
     int rgDiff = rgbArr[0] - rgbArr[1]; 
     int rbDiff = rgbArr[0] - rgbArr[2]; 
     // Filter out black, white and grays...... (tolerance within 10 pixels) 
     int tolerance = 10; 
     if (rgDiff > tolerance || rgDiff < -tolerance) 
      if (rbDiff > tolerance || rbDiff < -tolerance) { 
       return false; 
      }     
     return true; 
    } 
} 
1

Используя простой Java вы можете просто перебирать каждый пиксель и сосчитать, как часто содержится каждый цвет ...

псевдо-код:

Map<Color, Integer> color2counter; 
for (x : width) { 
    for (y : height) { 
     color = image.getPixel(x, y) 
     occurrences = color2counter.get(color) 
     color2counter.put(color, occurrences + 1) 
    } 
} 
0

Предполагая, что вы используете цветовую схему добавки, где (0,0,0) является черным и (255, 255, 255) является белым (исправьте меня, если я ошибаюсь). Кроме того, если вы просто хотите найти доминирующий цвет из RGB:

Одна из моих идей, которую любой из вас может свободно анализировать, состоит в том, чтобы иметь 3 переменные, каждая из которых хранит одно из значений RGB и добавляет к каждому из них их соответствующее значение каждого пикселя в изображении, а затем разделить на (255 * numOfPixels), чтобы получить соотношение цвета. Затем сравните 3 отношения: .60 для красного и .5 для зеленого означает, что красный цвет является более доминирующим.

Это просто идея, и, возможно, потребуется щипая ...

+0

Я использовал jamagick, для которого цвет используется как тип RGB, но таким образом я могу найти только клонирование изображения. Но у меня есть идея, что я могу обрезать изображение середины, поэтому я могу найти нужный цвет этой части, он снова даст тот же цвет. Я нахожу только доминирующий цвет:/ –

+0

@ ErçinAkçay. Если вы хотите обрезать изображение, вам обязательно нужен основной цвет на границах. например скажем, у вас большой квадрат, окруженный белым. Вы хотите определить цвет белого для обрезки, а не квадрат. –

4

Это сложная проблема. Например, если у вас небольшая площадь точно такого же цвета и большая площадь слегка разных оттенков другого цвета, тогда просто поиск цвета, который используется, вряд ли даст вам результат, который вы хотите. Вы получите лучший результат, определив набор цветов и, для каждого, диапазоны значений RGB, которые вы считаете «быть» этим цветом.

Эта тема подробно обсуждается на сервере дискурса ImageMagick, например: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12878

Смотрите также Fast way of getting the dominant color of an image

6

Я только что выпустила очень простой алгоритм, который может быть переведен в Java тривиальным. Он называется color-finder и работает в JavaScript.

Предлагаемые решения в этой теме могут быть отброшены несколькими белыми символами на изображении, тогда как мой действительно пытается найти наиболее заметный цвет, даже если все пиксели не совсем точно одного цвета.

Here is a live demo.

Сообщите мне, если вы сочтете это полезным.

1

Другим способом мы можем выполнить эту работу с помощью библиотеки Color Thief. Более подробную информацию можно найти here и here.

Кредит @svenwoltmann и @lokeshdhakar.

Смежные вопросы