根据 RGB 对 ArrayList<Color> 进行排序
Sorting an ArrayList<Color> based on RGB
我在尝试对 Color
的 ArrayList
进行排序时遇到问题。
我正在检索这张图片的所有颜色
imgRed.jpg
我使用的代码:
public static ArrayList<Color> getColors(BufferedImage img){
int height = img.getHeight();
int width = img.getWidth();
boolean found = false;
ArrayList<Color> List = new ArrayList<>();
for(int x=0;x<width;x++) {
for(int y=0;y<height;y++) {
found = false;
Color color = new Color(img.getRGB(x, y));
for(Color c : List) {
if(color.getRGB()<c.getRGB()+100 && color.getRGB()>c.getRGB()-100) {
found=true;
}
}
if(!found) {
List.add(color);
}
}
}
return List;
}
收集完所有颜色后,我将它们分类:
Collections.sort(Colors, Comparator.comparing(Color::getRed)
.thenComparing(Color::getGreen)
.thenComparing(Color::getBlue));
随后我创建了一个包含所有排序颜色的新图像:
public static void createImage(ArrayList<Color> Colors) {
int width=500;
int height=Colors.size()*10;
BufferedImage b_img = new BufferedImage(width,height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = b_img.createGraphics();
int partialHeight = 0;
int amount = Colors.size();
for(Color c : Colors) {
System.out.println("Colors remaining: "+amount);
graphics.setPaint ( c );
graphics.fillRect ( 0, partialHeight, b_img.getWidth(), partialHeight+10 );
partialHeight = partialHeight + 10;
amount--;
}
File outFile = new File("C:/test/img/out/testColor/outputRed4.png");
try {
ImageIO.write(b_img, "png", outFile);
} catch (IOException e) {
e.printStackTrace();
}
}
此函数生成此图像:outputRed.png
如您所见,颜色并没有真正排序。这是因为(我认为)颜色是根据其数值(红色、绿色、蓝色)排序的,并且因为 RGB 数值不是按我们的观点排序的。
我记得生成的图像没有两次颜色,所以该图像中的所有颜色都不同。
我的问题是:
我怎样才能按照每种颜色的所有阴影来排序所有颜色,而不会出现这种参差不齐的结果?
感谢大家
您遇到的问题是因为您正在获取 3 维数据(红色值、绿色值、蓝色值)并试图在 1 维(只有一个 List
index
参数).
如果您先按颜色的红色值排序,然后按绿色值,然后按蓝色值排序,则您收到的输出很可能正是您所期望的。请记住,此方法仅比较绿色值以对具有相同红色值的颜色进行排序,同样仅比较蓝色值以对具有相同红色 和 蓝色值的颜色进行排序。
也许它看起来 "jagged" 的原因是强度突然变化。鉴于输入图像几乎完全是不同强度的红色阴影,可能值得使用 Comparator.comparing(Color::getTotal)
,其中 getTotal()
定义为:
int getTotal() {
return getGreen() + getBlue() + getRed();
}
这将按强度(即亮度)排序,并使图像看起来不那么 "jagged",但在不仅仅是红色的图像上,颜色将不会在 "colour order" 或 "rainbow order".
同样,这是一个尝试将 3-d 数据映射到 1-d space 的问题。总是要做出妥协。
我在尝试对 Color
的 ArrayList
进行排序时遇到问题。
我正在检索这张图片的所有颜色 imgRed.jpg 我使用的代码:
public static ArrayList<Color> getColors(BufferedImage img){
int height = img.getHeight();
int width = img.getWidth();
boolean found = false;
ArrayList<Color> List = new ArrayList<>();
for(int x=0;x<width;x++) {
for(int y=0;y<height;y++) {
found = false;
Color color = new Color(img.getRGB(x, y));
for(Color c : List) {
if(color.getRGB()<c.getRGB()+100 && color.getRGB()>c.getRGB()-100) {
found=true;
}
}
if(!found) {
List.add(color);
}
}
}
return List;
}
收集完所有颜色后,我将它们分类:
Collections.sort(Colors, Comparator.comparing(Color::getRed)
.thenComparing(Color::getGreen)
.thenComparing(Color::getBlue));
随后我创建了一个包含所有排序颜色的新图像:
public static void createImage(ArrayList<Color> Colors) {
int width=500;
int height=Colors.size()*10;
BufferedImage b_img = new BufferedImage(width,height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = b_img.createGraphics();
int partialHeight = 0;
int amount = Colors.size();
for(Color c : Colors) {
System.out.println("Colors remaining: "+amount);
graphics.setPaint ( c );
graphics.fillRect ( 0, partialHeight, b_img.getWidth(), partialHeight+10 );
partialHeight = partialHeight + 10;
amount--;
}
File outFile = new File("C:/test/img/out/testColor/outputRed4.png");
try {
ImageIO.write(b_img, "png", outFile);
} catch (IOException e) {
e.printStackTrace();
}
}
此函数生成此图像:outputRed.png
如您所见,颜色并没有真正排序。这是因为(我认为)颜色是根据其数值(红色、绿色、蓝色)排序的,并且因为 RGB 数值不是按我们的观点排序的。 我记得生成的图像没有两次颜色,所以该图像中的所有颜色都不同。
我的问题是:
我怎样才能按照每种颜色的所有阴影来排序所有颜色,而不会出现这种参差不齐的结果?
感谢大家
您遇到的问题是因为您正在获取 3 维数据(红色值、绿色值、蓝色值)并试图在 1 维(只有一个 List
index
参数).
如果您先按颜色的红色值排序,然后按绿色值,然后按蓝色值排序,则您收到的输出很可能正是您所期望的。请记住,此方法仅比较绿色值以对具有相同红色值的颜色进行排序,同样仅比较蓝色值以对具有相同红色 和 蓝色值的颜色进行排序。
也许它看起来 "jagged" 的原因是强度突然变化。鉴于输入图像几乎完全是不同强度的红色阴影,可能值得使用 Comparator.comparing(Color::getTotal)
,其中 getTotal()
定义为:
int getTotal() {
return getGreen() + getBlue() + getRed();
}
这将按强度(即亮度)排序,并使图像看起来不那么 "jagged",但在不仅仅是红色的图像上,颜色将不会在 "colour order" 或 "rainbow order".
同样,这是一个尝试将 3-d 数据映射到 1-d space 的问题。总是要做出妥协。