Java使用BuffereImage转换灰度和深褐色版本的图像
我想读取一幅图像,转换并输出原始图像、灰度版和深褐色版。我在转换方面有问题,对BuffereImage不太熟悉,尤其是getRGB和setRGB方法有问题。到目前为止,我有这个Java使用BuffereImage转换灰度和深褐色版本的图像,java,image-processing,Java,Image Processing,我想读取一幅图像,转换并输出原始图像、灰度版和深褐色版。我在转换方面有问题,对BuffereImage不太熟悉,尤其是getRGB和setRGB方法有问题。到目前为止,我有这个 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; im
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] ) );
}
}
}
导入java.awt.Color;
导入java.awt.Graphics2D;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.net.URL;
导入javax.imageio.IIOImage;
导入javax.imageio.imageio;
导入javax.imageio.ImageWriteParam;
导入javax.imageio.ImageWriter;
导入javax.imageio.plugins.jpeg.JPEGImageWriteParam;
导入javax.imageio.stream.ImageOutputStream;
公共类变色{
静态缓冲区映像读取映像(字符串Pic)引发异常{
buffereImage image=ImageIO.read(新文件(“Pic.jpg”);
返回(图像);
}
公共静态void saveImage(buffereImage img,File File)引发IOException{
ImageWriter=null;
java.util.Iterator iter=ImageIO.getImageWritersByFormatName(“jpg”);
if(iter.hasNext()){
writer=(ImageWriter)iter.next();
}
ImageOutputStream ios=ImageIO.createImageOutputStream(文件);
writer.setOutput(ios);
ImageWriteParam参数=新的JPEGImageWriteParam(java.util.Locale.getDefault());
参数setCompressionMode(ImageWriteParam.MODE_显式);
参数设置压缩质量(0.98f);
writer.write(null,新IIOImage(img,null,null),param);
}
公共静态BuffereImage color2gray(BuffereImage inImage){
int-width=inImage.getWidth();
int height=inImage.getHeight();
BuffereImage outImage=新的BuffereImage(宽度、高度、BuffereImage.TYPE_3BYTE_BGR);
对于(inti=0;i来说,灰度缩放是相当容易的,乌贼墨并不是那么多
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;
}
}
导入java.awt.EventQueue;
导入java.awt.GridBagLayout;
导入java.awt.color.ColorSpace;
导入java.awt.image.buffereImage;
导入java.awt.image.ColorConvertOp;
导入java.awt.image.WritableRaster;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
导入javax.swing.ImageIcon;
导入javax.swing.JLabel;
导入javax.swing.JOptionPane;
导入javax.swing.JPanel;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类颜色更改{
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
}
试一试{
BuffereImage master=ImageIO.read(新文件(“C:\\hold\\thumbnails\\\\u cg\u 836\uuuuuuuuuuuuuuuuuuuuuuuuuuu倾斜式风车\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
缓冲图像灰度=总灰度(主);
BuffereImage乌贼墨=toSepia(母版,80);
JPanel panel=newjpanel(newgridbagloayout());
添加(新JLabel(新图像图标(主));
添加(新的JLabel(新的图像图标(灰色));
添加(新JLabel(新ImageIcon(深褐色));
showMessageDialog(空,面板);
}捕获(IOEX异常){
例如printStackTrace();
}
}
});
}
公共静态BuffereImage toGrayScale(BuffereImage主机){
BuffereImage gray=新的BuffereImage(master.getWidth(),master.getHeight(),BuffereImage.TYPE_INT_ARGB);
//自动对话。。。。
ColorConvertOp=新的ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY)),null;
op.过滤器(主过滤器,灰色);
返回灰色;
}
公共静态BuffereImage toSepia(BuffereImage img,int sepiaIntensity){
BuffereImage sepia=新的BuffereImage(img.getWidth(),img.getHeight(),BuffereImage.TYPE_INT_RGB);
//试试这个。20很好用,是推荐的
//由另一个开发人员创建。0生成黑白图像
int-sepiaDepth=20;
int w=img.getWidth();
inth=img.getHeight();
WritableRaster raster=sepia.getRaster();
//我们需要每像素3个整数(用于R、G、B颜色值)。
int[]像素=新的int[w*h*3];
getgraster().getPixels(0,0,w,h,像素);
//每个像素一次处理3个整数。每个像素有3个RGB
//数组中的颜色
对于(int i=0;i255){
r=255;
}
如果(g>255){
g=255;
}
如果(b>255){
b=255;
}
//加深蓝色以增加乌贼墨效果
b-=乌贼墨强度;
//如果超出范围,则进行规范化
if(b<0){
b=0;
}
如果(b>255){
b=255;
}
像素[i]=r;
像素[i+1]=g;
像素[i+2]=b;
}
光栅设置像素(0,0,w,h,像素);
返黑;
}
}
您可以找到sepia算法的原始发布
因为我很固执…我改变了sepia算法来处理基于alpha的图像
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;
}
publicstaticbufferedimage-toSepia(BufferedImage-img,int-sepiaensity){
BuffereImage乌贼墨=新B
public static BufferedImage toSepia(BufferedImage image, int sepiaIntensity) {
int width = image.getWidth();
int height = image.getHeight();
int sepiaDepth = 20;
int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width);
for (int i = 0; i < imagePixels.length; i++) {
int color = imagePixels[i];
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = (color) & 0xff;
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;
}
imagePixels[i] = (color & 0xff000000) + (r << 16) + (g << 8) + b;
}
BufferedImage res = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
res.setRGB(0, 0, width, height, imagePixels, 0, width);
return res;
}
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class FilterApp {
public static ClassLoader loader = FilterApp.class.getClassLoader();
public static String outputDir = "build";
public static void main(String[] args) {
try {
BufferedImage srcImage = loadImage("lobster.jpg");
File dir = new File(outputDir);
if (!dir.exists()) {
dir.mkdirs();
}
for (FilterType filter : FilterType.values()) {
BufferedImage filteredImage = filter.applyFilter(srcImage);
String filename = String.format("%s/lobster_%s", outputDir, filter.name().toLowerCase());
writeImage(filteredImage, filename, "jpg");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static BufferedImage loadImage(String filename) throws IOException {
return ImageIO.read(loader.getResourceAsStream("resources/" + filename));
}
private static void writeImage(BufferedImage image, String filename, String ext) throws IOException {
ImageIO.write(image, ext, new File(filename + '.' + ext));
}
}
import java.awt.image.BufferedImage;
import filter.GreyscaleFilter;
import filter.ImageFilter;
import filter.InvertFilter;
import filter.SepiaFilter;
public enum FilterType {
GREYSCALE(new GreyscaleFilter()),
INVERT(new InvertFilter()),
SEPIA_10(new SepiaFilter(10));
private ImageFilter filter;
public ImageFilter getFilter() { return filter; }
public BufferedImage applyFilter(BufferedImage img) {
return this.filter.apply(img);
}
private FilterType(ImageFilter filter) {
this.filter = filter;
}
}
package filter;
import java.awt.image.BufferedImage;
/** Common Interface for different filters. */
public interface ImageFilter {
public BufferedImage apply(BufferedImage img);
}
package filter;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
public class GreyscaleFilter implements ImageFilter {
@Override
public BufferedImage apply(BufferedImage img) {
BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
op.filter(img, result);
return result;
}
}
package filter;
import java.awt.Color;
import java.awt.image.BufferedImage;
public class InvertFilter implements ImageFilter {
@Override
public BufferedImage apply(BufferedImage img) {
BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
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 = 255 - color.getRed();
int g = 255 - color.getGreen();
int b = 255 - color.getBlue();
color = new Color(r, g, b, color.getAlpha());
result.setRGB(x, y, color.getRGB());
}
}
return result;
}
}
package filter;
import java.awt.Color;
import java.awt.image.BufferedImage;
// Algorithm obtained from http://stackoverflow.com/questions/21899824
public class SepiaFilter implements ImageFilter {
private int intensity;
public void setIntensity(int intensity) { this.intensity = intensity; }
public int getIntensity() { return intensity; }
public SepiaFilter(int intensity) {
this.intensity = intensity;
}
@Override
public BufferedImage apply(BufferedImage img) {
BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
// 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();
// 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 -= this.intensity;
// normalize if out of bounds
if (b < 0) { b = 0; }
if (b > 255) { b = 255; }
color = new Color(r, g, b, color.getAlpha());
result.setRGB(x, y, color.getRGB());
}
}
return result;
}
}