我正在编写一个程序来生成程序图像,但是当我运行它时,它会跳过像素。我的意思是生成的图像看起来像像素级的棋盘。相反,我希望它顺利。
public class Test {
public static void main(String[] args) {
JFrame f = new JFrame();
BufferedImage bi = create(new BufferedImage(1024, 1024,
BufferedImage.TYPE_INT_ARGB));
f.getContentPane().add(new JLabel(new ImageIcon(bi)));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
save(bi, "name.png");
}
//creates the procedural image
private static BufferedImage create(BufferedImage bi) {
for (int i = 0; i < bi.getWidth(); i++) {
for (int j = 0; j < bi.getHeight(); j++) {
Context c = new Context(bi, i, j);
int red = red(i, j, c) + 128;
int green = green(i, j, c) + 128;
int blue = blue(i, j, c) + 128;
bi.setRGB(i, j, new Color(red, green, blue).getRGB());
}
}
return bi;
}
//saves image to file
private static void save(BufferedImage img, String filename) {
try {
File f = new File(filename);
System.out.println(f.getAbsolutePath());
ImageIO.write(img, "png", f);
} catch (IOException e) {
e.printStackTrace();
}
}
//PIXEL FUNCTIONS - returns the color for specified pixel
private static byte red(int i, int j, Context context) {
return (byte) (Context.average(context.north, context.west).getRed()
+ (Math.random() * 5.5) - 2);
}
private static byte green(int i, int j, Context context) {
return (byte) (Context.average(context.north, context.west).getGreen()
+ (Math.random() * 3.46) - 1);
}
private static byte blue(int i, int j, Context context) {
return (byte) (Context.average(context.north, context.west).getBlue()
+ (Math.random() * 17.5) - 8);
}
//Represents the surrounding pixels of the pixel passed into the constructor
static private class Context {
public Color north;
public Color northeast;
public Color east;
public Color southeast;
public Color south;
public Color southwest;
public Color west;
public Color northwest;
private static final Color DEFAULT = Color.GRAY;
//Returns the mean color
public static Color average(Color... colors) {
int redtot = 0;
int greentot = 0;
int bluetot = 0;
for (Color c : colors) {
redtot += c.getRed();
greentot += c.getGreen();
bluetot += c.getBlue();
}
int red = redtot / colors.length;
int green = greentot / colors.length;
int blue = bluetot / colors.length;
return new Color(red, green, blue);
}
public Context(BufferedImage image, int x, int y) {
north = DEFAULT;
northeast = DEFAULT;
east = DEFAULT;
southeast = DEFAULT;
south = DEFAULT;
southwest = DEFAULT;
west = DEFAULT;
northwest = DEFAULT;
try {
north = new Color(image.getRGB(x, y - 1));
} catch (ArrayIndexOutOfBoundsException e) {
}
try {
northeast = new Color(image.getRGB(x + 1, y - 1));
} catch (ArrayIndexOutOfBoundsException e) {
}
try {
east = new Color(image.getRGB(x + 1, y));
} catch (ArrayIndexOutOfBoundsException e) {
}
try {
southeast = new Color(image.getRGB(x + 1, y + 1));
} catch (ArrayIndexOutOfBoundsException e) {
}
try {
south = new Color(image.getRGB(x, y + 1));
} catch (ArrayIndexOutOfBoundsException e) {
}
try {
southwest = new Color(image.getRGB(x - 1, y + 1));
} catch (ArrayIndexOutOfBoundsException e) {
}
try {
west = new Color(image.getRGB(x - 1, y));
} catch (ArrayIndexOutOfBoundsException e) {
}
try {
northwest = new Color(image.getRGB(x - 1, y - 1));
} catch (ArrayIndexOutOfBoundsException e) {
}
}
}
}
这是生成的图片:
这是放大的:
造成这种行为的原因是什么?
答案 0 :(得分:1)
我不熟悉您用来计算这些颜色的任何公式,但是方格图案似乎来自于您为每个颜色组件添加128。可能有些溢出导致值的反弹......
int red = red(i, j, c) + 128;
int green = green(i, j, c) + 128;
int blue = blue(i, j, c) + 128;
至少,如果我删除+ 128
,我会得到一个正确的(对我而言)图像。虽然我不确定这对你想做的事情是否仍然有效。
这是我提出的快速修复方法,但可能还有其他更好的方法。使用Math.max()
是因为您将从至少第一个像素的无效值中获得异常。 (也许这就是你首先添加128的原因?)
int red = Math.max(0, red(i, j, c));
int green = Math.max(0, green(i, j, c));
int blue = Math.max(0, blue(i, j, c));
放大时图像显示正常(对我而言):