I am trying to read an image and output it as new grayscale and sepia version. I have figured out most of it, but the conversion only works for some images. For others, it just leads to an error message:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.ByteInterleavedRaster.getDataElements(ByteInterleavedRaster.java:318)
at java.awt.image.BufferedImage.getRGB(BufferedImage.java:918)
at ChangeColor.color2gray(ChangeColor.java:64)
at ChangeColor.main(ChangeColor.java:129)
I think it has something to do with the rgb values of the images, but I'm not sure how to adjust that to make this code work for any image. Help would be appreciated, thank you.
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 fname ) throws Exception {
BufferedImage image = ImageIO.read( new File(fname) );
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++){
{
int pic= inImage.getRGB(i,j);
int in_r = ((pic>>16) & 0xFF);
int in_g = ((pic>>8) & 0xFF);
int in_b = (pic & 0xFF);
float gray = (float)(in_r * 0.2126 + in_g * 0.7152 + in_b * 0.0722)/256;
Color color = new Color (gray, gray, gray);
int RGB = color.getRGB();
outImage.setRGB (i,j,RGB);
}
}
}
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++){
{
int pic= inImage.getRGB(i,j);
int in_r = ((pic>>16) & 0xFF);
int in_g = ((pic>>8) & 0xFF);
int in_b = (pic & 0xFF);
float out_r = (float)(((in_r * .393) + (in_g *.769) + (in_b * .189))/256);
if (out_r>1)
out_r = 1;
float out_g = (float)(((in_r * .349) + (in_g *.686) + (in_b * .168))/256);
if (out_g>1)
out_g = 1;
float out_b = (float)(((in_r * .272) + (in_g *.534) + (in_b * .131))/256);
if (out_b>1)
out_b = 1;
Color color = new Color (out_r, out_g, out_b);
int RGB = color.getRGB();
outImage.setRGB (i,j,RGB);
}
}
}
return( outImage );
}
public static void main(String[] args) throws Exception {
BufferedImage colorImage, grayImage, sepiaImage;
if (args.length != 1)
System.out.println( "usage is: java ChangeColor filename" );
else
{
colorImage = readImage ( args[0] );
grayImage = color2gray ( colorImage );
sepiaImage = color2sepia( colorImage );
saveImage( grayImage, new File( "gray" + args[0] ) );
saveImage( sepiaImage, new File( "sepia"+ args[0] ) );
}
}
}