生成的图像会跳过像素

时间:2014-08-14 18:32:53

标签: java image pixel

我正在编写一个程序来生成程序图像,但是当我运行它时,它会跳过像素。我的意思是生成的图像看起来像像素级的棋盘。相反,我希望它顺利。

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) {
            }
        }
    }
}

这是生成的图片:generated image

这是放大的:zoom

造成这种行为的原因是什么?

1 个答案:

答案 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));

放大时图像显示正常(对我而言):

enter image description here