Java使用BufferedImage转换图像的灰度和棕褐色版本 [英] Java Convert a greyscale and sepia version of an image with BufferedImage

查看:1617
本文介绍了Java使用BufferedImage转换图像的灰度和棕褐色版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想读取图像并转换并输出原始图像,灰度版本和棕褐色版本。我在转换时遇到问题,对BufferedImage不太熟悉,特别是遇到了getRGB和setRGB方法的问题。到目前为止我有这个

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 BufferedImage, and especially having problems with getRGB and setRGB method. I have this so far

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;

public class ChangeColor{
  static BufferedImage readImage( String Pic ) throws Exception {

    BufferedImage image = ImageIO.read( new File("Pic.jpg") );
    return( image );
  }

  public static void saveImage( BufferedImage img, File file ) throws IOException {

        ImageWriter      writer = null;
        java.util.Iterator iter = ImageIO.getImageWritersByFormatName("jpg");

        if( iter.hasNext() ){
            writer = (ImageWriter)iter.next();
        }

        ImageOutputStream ios = ImageIO.createImageOutputStream( file );
        writer.setOutput(ios);

        ImageWriteParam param = new JPEGImageWriteParam( java.util.Locale.getDefault() );
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
        param.setCompressionQuality(0.98f);

        writer.write(null, new IIOImage( img, null, null ), param);

    }

  public static BufferedImage color2gray( BufferedImage inImage ) {

    int            width    = inImage.getWidth();
    int            height   = inImage.getHeight();
    BufferedImage  outImage = new BufferedImage( width, height, BufferedImage.TYPE_3BYTE_BGR );

    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
           Color c = new Color(image.getRGB(j, i));
           int red = (int)(c.getRed() * 0.2126);
           int green = (int)(c.getGreen() * 0.7152);
           int blue = (int)(c.getBlue() *0.0722);
           Color newColor = new Color(red+green+blue,
           red+green+blue,red+green+blue);
           image.setRGB(j,i,newColor.getRGB());
           }
    }

    return( outImage );
  }

  public static BufferedImage color2sepia( BufferedImage inImage ) {

    int            width    = inImage.getWidth();
    int            height   = inImage.getHeight();
    BufferedImage  outImage = new BufferedImage( width, height, BufferedImage.TYPE_3BYTE_BGR );
    for(int i=0; i<height; i++){
        for(int j=0; j<width; j++){
           Color c = new Color(image.getRGB(j, i));
           int red = (int)(c.getRed());
           int green = (int)(c.getGreen());
           int blue = (int)(c.getBlue());
           Color newColor = new Color(red* .393)+(green*.769)+(blue* .189),
           (red* .349)+(green*.686)+(blue* .168),(red* .272)+(green*.534)+(blue* .131);
           image.setRGB(j,i,newColor.getRGB());
           }
    }
    return( outImage );
  }



  public static void main(String[] args) throws Exception {

    BufferedImage colorImage, grayImage, sepiaImage;

    if (args.length != 1)
        System.out.println( "" );
    else
    {
        colorImage = readImage  ( args[0] );
    grayImage  = color2gray ( colorImage );
    sepiaImage = color2sepia( colorImage );

    saveImage( grayImage,  new File( "greyPic.jpg" + args[0] ) );
    saveImage( sepiaImage, new File( "sepiaPic.jpg"+ args[0] ) );
    }
  }

}

这是输出应该是什么样子的图像:

This is an image of what the output should look like:


谢谢。

推荐答案

灰度缩放相当容易,棕褐色不是那么多。我从网上偷了算法...

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

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;
    }
}

您可以找到sepia算法的原始发布< a href =https://groups.google.com/forum/#!topic/comp.lang.java.programmer/nSCnLECxGdA\"rel =noreferrer>这里

You can find the original posting for the sepia algorithm here

因为我很顽固......我改变了棕褐色算法来处理基于alpha的图像......

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;
}

这篇关于Java使用BufferedImage转换图像的灰度和棕褐色版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆