2012-05-10 72 views

Trả lời

7

trong java lặp trên mỗi pixel và xác định màu

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

Sử dụng java đơn giản bạn chỉ có thể lặp qua mỗi pixel và đếm mức độ thường xuyên mỗi màu được chứa ...

pseudo-code:

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

giả sử sử dụng bảng phối màu phụ gia, trong đó (0,0,0) là màu đen và (255, 255, 255) là màu trắng (đúng nếu tôi nhầm). Ngoài ra, nếu bạn chỉ muốn tìm màu chủ đạo của RGB:

Một ý tưởng mà bạn có, miễn là xem xét 3 biến mà mỗi giá trị lưu trữ một trong các giá trị RGB và thêm vào mỗi chúng là giá trị thích hợp của mỗi điểm ảnh trong hình ảnh và sau đó chia cho (255 * numOfPixels) để có được tỷ lệ màu sắc. Sau đó so sánh 3 tỷ lệ: .60 cho màu đỏ và 0,5 cho màu xanh lá cây có nghĩa là màu đỏ chiếm ưu thế hơn.

Đây chỉ là ý tưởng và có thể cần tinh chỉnh ...

+0

tôi sử dụng jamagick cho màu sắc được sử dụng như loại RGB nhưng với cách này tôi chỉ có thể tìm thấy clor avarage của hình ảnh. Nhưng tôi có một ý tưởng tôi có thể cắt hình ảnh của giữa vì vậy tôi có thể tìm thấy màu sắc avarage của phần đó nó sẽ cung cấp cho gần như cùng một màu sắc một lần nữa. Tôi chỉ tìm thấy màu chủ đạo:/ –

+0

@ ErçinAkçay Nếu bạn muốn cắt hình ảnh, chắc chắn bạn muốn màu chính ở biên giới. ví dụ. nói rằng bạn có một hình vuông lớn được bao quanh bởi màu trắng. Bạn muốn phát hiện màu trắng để cắt, không phải hình vuông. –

4

Đây là một vấn đề phức tạp. Ví dụ: nếu bạn có một khu vực nhỏ có cùng màu sắc và diện tích lớn với các màu hơi khác nhau, thì chỉ cần tìm màu được sử dụng nhiều nhất là không thể cho bạn kết quả mong muốn. Bạn sẽ nhận được kết quả tốt hơn bằng cách xác định một tập hợp các màu và, đối với mỗi dải, các giá trị RGB mà bạn cho là 'là' màu đó.

Chủ đề này đã được thảo luận tại chiều dài trên máy chủ thuyết ImageMagick, ví dụ: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12878

Xem thêm Fast way of getting the dominant color of an image

6

tôi vừa phát hành một thuật toán rất đơn giản mà có thể được dịch bằng Java trivially. Nó được gọi là color-finder và hoạt động trong JavaScript.

Các giải pháp được đề xuất trong chuỗi này có thể được ném ra bởi một vài ký tự trắng trong hình ảnh, trong khi tôi thực sự cố gắng tìm màu nổi bật nhất, ngay cả khi tất cả các pixel không thực sự chính xác cùng màu.

Here is a live demo.

Hãy cho tôi biết nếu bạn thấy hữu ích.

1

Nói cách khác, chúng tôi có thể thực hiện công việc này với thư viện Color Thief. Bạn có thể tìm thêm thông tin herehere.

Ghi có vào @svenwoltmann và @lokeshdhakar.

Các vấn đề liên quan