Java 根据图像修改背景颜色(主题)
我试图找到最适合加载图像的颜色,并将其应用到背景中。以适应图像并使UI感觉更自然。 到目前为止,我发现了两个方案: 1> 平均像素数(代码如下):Java 根据图像修改背景颜色(主题),java,image,swing,image-processing,colors,Java,Image,Swing,Image Processing,Colors,我试图找到最适合加载图像的颜色,并将其应用到背景中。以适应图像并使UI感觉更自然。 到目前为止,我发现了两个方案: 1> 平均像素数(代码如下): 最终颜色适应范围(BuffereImage img){ 长avgr=0,avgb=0,avgg=0; 对于(int i=0;i
最终颜色适应范围(BuffereImage img){
长avgr=0,avgb=0,avgg=0;
对于(int i=0;i
2> 将像素分组到固定的颜色箱中(代码如下):
Map createBins(){
Map bins=new HashMap();
垃圾箱。放置(颜色:红色,0);
箱子放置(颜色为洋红色,0);
箱子。放置(颜色为橙色,0);
垃圾箱。放置(颜色为粉红色,0);
箱子。放置(颜色为黄色,0);
箱子放置(颜色为浅灰色,0);
垃圾箱。放置(颜色为绿色,0);
箱子放置(颜色为灰色,0);
箱子放置(颜色为深灰色,0);
箱子放置(颜色为青色,0);
箱子。放置(颜色为蓝色,0);
箱子。放置(颜色为黑色,0);
回收箱;
}
int比较(颜色a、颜色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());
}
BuffereImage适应组(BuffereImage img){
Map bins=createBins();
对于(int i=0;i最大值){
max=整数;
c=entry.getKey();
}
}
返回c;
}
但是分组产生了奇怪的结果……左侧是分组产生的颜色,右侧是图像
为什么会产生这样的结果??? averaing正在产生更正确的结果:
我认为问题在于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)2)1/2
应用于Java,结果是修改了compare(颜色a,颜色b)
1) 为了更快地获得更好的帮助,请发布一个。2) 在那堆乱七八糟的词中没有“?”这个词。如果您有问题,请添加它,并在末尾打上“?”。操作顺序、值等。物理和数学公式也是如此。如果你试图找到一个物体的变化率,但是翻转了位置,你会得到错误的结果。伙计,我希望你注意到它正在变平方,我们知道,(a-b)^2==(b-a)^2是的,我认为这是个好主意。但我绝对推荐使用上面的算法(我有类似的问题,这个算法比欧几里得距离更好)。
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;
}
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));
}
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() ));
}