Java Convert a greyscale and sepia version of an image with BufferedImage

前端 未结 3 1653
时光说笑
时光说笑 2020-12-21 13:42

I want to read an image and convert and output the original image, a greyscale version, and a sepia version. I am having trouble with the conversion, not very familiar with

3条回答
  •  伪装坚强ぢ
    2020-12-21 14:12

    Gray scaling is rather easy, sepia not so much. I stole the algorithm off the net...

    Convert

    import java.awt.EventQueue;
    import java.awt.GridBagLayout;
    import java.awt.color.ColorSpace;
    import java.awt.image.BufferedImage;
    import java.awt.image.ColorConvertOp;
    import java.awt.image.WritableRaster;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class ColorAlteration {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
                    try {
                        BufferedImage master = ImageIO.read(new File("C:\\hold\\thumbnails\\_cg_836___Tilting_Windmills___by_Serena_Clearwater.png"));
                        BufferedImage gray = toGrayScale(master);
                        BufferedImage sepia = toSepia(master, 80);
    
                        JPanel panel = new JPanel(new GridBagLayout());
                        panel.add(new JLabel(new ImageIcon(master)));
                        panel.add(new JLabel(new ImageIcon(gray)));
                        panel.add(new JLabel(new ImageIcon(sepia)));
    
                        JOptionPane.showMessageDialog(null, panel);
    
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            });
        }
    
        public static BufferedImage toGrayScale(BufferedImage master) {
            BufferedImage gray = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
    
            // Automatic converstion....
            ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
            op.filter(master, gray);
    
            return gray;
        }
    
        public static BufferedImage toSepia(BufferedImage img, int sepiaIntensity) {
    
            BufferedImage sepia = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
            // Play around with this.  20 works well and was recommended
            //   by another developer. 0 produces black/white image
            int sepiaDepth = 20;
    
            int w = img.getWidth();
            int h = img.getHeight();
    
            WritableRaster raster = sepia.getRaster();
    
            // We need 3 integers (for R,G,B color values) per pixel.
            int[] pixels = new int[w * h * 3];
            img.getRaster().getPixels(0, 0, w, h, pixels);
    
            //  Process 3 ints at a time for each pixel.  Each pixel has 3 RGB
            //    colors in array
            for (int i = 0; i < pixels.length; i += 3) {
                int r = pixels[i];
                int g = pixels[i + 1];
                int b = pixels[i + 2];
    
                int gry = (r + g + b) / 3;
                r = g = b = gry;
                r = r + (sepiaDepth * 2);
                g = g + sepiaDepth;
    
                if (r > 255) {
                    r = 255;
                }
                if (g > 255) {
                    g = 255;
                }
                if (b > 255) {
                    b = 255;
                }
    
                // Darken blue color to increase sepia effect
                b -= sepiaIntensity;
    
                // normalize if out of bounds
                if (b < 0) {
                    b = 0;
                }
                if (b > 255) {
                    b = 255;
                }
    
                pixels[i] = r;
                pixels[i + 1] = g;
                pixels[i + 2] = b;
            }
            raster.setPixels(0, 0, w, h, pixels);
    
            return sepia;
        }
    }
    

    You can find the original posting for the sepia algorithm here

    And because I'm stubborn...I changed the sepia algorithm to work with alpha based images...

    public static BufferedImage toSepia(BufferedImage img, int sepiaIntensity) {
    
        BufferedImage sepia = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
        // Play around with this.  20 works well and was recommended
        //   by another developer. 0 produces black/white image
        int sepiaDepth = 20;
    
        int w = img.getWidth();
        int h = img.getHeight();
    
        WritableRaster raster = sepia.getRaster();
    
        // We need 3 integers (for R,G,B color values) per pixel.
        int[] pixels = new int[w * h * 3];
        img.getRaster().getPixels(0, 0, w, h, pixels);
    
        for (int x = 0; x < img.getWidth(); x++) {
            for (int y = 0; y < img.getHeight(); y++) {
    
                int rgb = img.getRGB(x, y);
                Color color = new Color(rgb, true);
                int r = color.getRed();
                int g = color.getGreen();
                int b = color.getBlue();
                int gry = (r + g + b) / 3;
    
                r = g = b = gry;
                r = r + (sepiaDepth * 2);
                g = g + sepiaDepth;
    
                if (r > 255) {
                    r = 255;
                }
                if (g > 255) {
                    g = 255;
                }
                if (b > 255) {
                    b = 255;
                }
    
                // Darken blue color to increase sepia effect
                b -= sepiaIntensity;
    
                // normalize if out of bounds
                if (b < 0) {
                    b = 0;
                }
                if (b > 255) {
                    b = 255;
                }
    
                color = new Color(r, g, b, color.getAlpha());
                sepia.setRGB(x, y, color.getRGB());
    
            }
        }
    
        return sepia;
    }
    

提交回复
热议问题