Question

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

      }
Was it helpful?

Solution

Your error is here:

      for(int i=0; i<height; i++){
          for(int j=0; j<width; j++){
            {
                int pic= inImage.getRGB(i,j);

You have swapped width and height, so you unless the image is a perfect square you will get the error you posted.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top