簡體   English   中英

根據圖像修改背景色(主題)

[英]Modification of Back Ground color(theme) According to an image

我試圖找到最適合加載的圖像的顏色,並將其應用到背景中。 適應圖像並使UI感覺更自然。 到目前為止,我發現了2個方案:

1>平均像素(以下代碼):

final Color acclimatizeAverage(BufferedImage img) {
        long avgr = 0, avgb = 0, avgg = 0;
        for (int i = 0; i < img.getWidth(); i++) {
            for (int j = 0; j < img.getHeight(); j++) {
               Color c = new Color(img.getRGB(i, j));
               avgr += c.getRed(); avgb += c.getBlue(); avgg += c.getGreen();
            }
        }
        avgr = (avgr/(img.getHeight()*img.getWidth()));
        avgg = (avgg/(img.getHeight()*img.getWidth()));
        avgb = (avgb/(img.getHeight()*img.getWidth()));
        Color c = new Color((int)avgr, (int)avgg, (int)avgb);
        return c;
    }

2>將像素分組到Colors的固定容器中(以下代碼):

 Map<Color, Integer> createBins() {
        Map<Color, Integer> bins = new HashMap<>();
        bins.put(Color.red, 0);
        bins.put(Color.magenta, 0);
        bins.put(Color.orange, 0);
        bins.put(Color.PINK, 0);
        bins.put(Color.yellow, 0);
        bins.put(Color.LIGHT_GRAY, 0);
        bins.put(Color.GREEN, 0);
        bins.put(Color.GRAY, 0);
        bins.put(Color.DARK_GRAY, 0);
        bins.put(Color.CYAN, 0);
        bins.put(Color.BLUE, 0);
        bins.put(Color.BLACK, 0);
        return bins;
    }

    int compare(Color a, Color b) {
        return (int)Math.sqrt((a.getRed() - b.getRed())*(a.getRed() - b.getRed()) 
                + (a.getBlue() - b.getBlue())*(a.getBlue() - b.getBlue()) 
                + (a.getGreen()- b.getGreen())*(a.getGreen()- b.getGreen()));
    }

    BufferedImage acclimatizeGrouping(BufferedImage img) {
        Map<Color, Integer> bins = createBins();
        for (int i = 0; i < img.getWidth(); i++) {
            int min = Integer.MAX_VALUE; Color minC = null;
            for (int j = 0; j < img.getHeight(); j++) {
               Color c = new Color(img.getRGB(i, j));
                for (Map.Entry<Color, Integer> entry : bins.entrySet()) {
                    Integer integer = compare(entry.getKey(), c);
                    if(integer < min) {
                        min = integer;
                        minC = entry.getKey();
                    }
                }
                bins.put(minC, bins.get(minC)+1);
            }
        }
        int max = -1, n = 1; Color c = null;
        for (Map.Entry<Color, Integer> entry : bins.entrySet()) {
            Integer integer = entry.getValue();
            if(integer > max) {
                max = integer;
                c = entry.getKey();
            }
        }
        return c;
    }

但是分組產生了奇怪的結果。
左側是分組產生的顏色,右側是圖像
為什么會產生這樣的結果? 左側是分組產生的顏色,右側是圖像

平均產生更正確的結果: 在此處輸入圖片說明

我認為問題在於RGB不是人類的歐式空間。 您可以使用歐幾里得距離來比較顏色,但是這對人的色彩感覺不利。 有關更多信息,請參見此鏈接

編輯:更精確,您應該使用此算法:

typedef struct {
   unsigned char r, g, b;
} RGB;

double ColourDistance(RGB e1, RGB e2)
{
  long rmean = ( (long)e1.r + (long)e2.r ) / 2;
  long r = (long)e1.r - (long)e2.r;
  long g = (long)e1.g - (long)e2.g;
  long b = (long)e1.b - (long)e2.b;
  return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
}

問題是,您的compare(Color a, Color b)方法未正確實現,可以使用Math.pow()方法進行一些基本的重構。

以編程方式查找相似顏色的基本公式是

((r2-r1) 2 +(g2-g1) 2 +(b2-b1) 21/2

應用於Java,導致修改后的compare(Color a, Color b)

int compare(Color a, Color b){
  return Math.sqrt(( Math.pow( b.getRed() - a.getRed() ) 
                   + ( Math.pow( b.getGreen() - a.getGreen() )
                   + ( Math.pow( b.getBlue() - a.getBlue() ));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM