1 Reply Latest reply: Oct 21, 2011 10:03 AM by 684462 RSS

    Error saving Rotated image using JAI

    684462
      Hello,

      I am using JAI library for image processing and getting this error couldn’t figured out any solution. It would be much appreciate If I can get any help.

      I am trying to rotate Tiff image using Transpose or Rotate operation and then save that but neither of this two is working. After the rotation operation is making image very large so I’m using compression type TIFFEncodeParam.COMPRESSION_GROUP3_2D which is throwing following error:
      “Exception in thread "main" java.lang.Error: Bilevel encodings are supported for bilevel images only.
      at com.sun.media.jai.codecimpl.TIFFImageEncoder.encode(TIFFImageEncoder.java:388)
      at com.sun.media.jai.codecimpl.TIFFImageEncoder.encode(TIFFImageEncoder.java:161)”

      I tried all the other compression types as well but it’s not saving my changes.

      For Image processing I’m using subsequent versions of jar files JAI_CODEC_1.1.2_01, JAI_CORE_1.1.2_01, JAI_IMAGEIO_1.1

      Please find the code I'm using below:

      THANK YOU VERY MUCH in advance for your time and concerns. I will look forward to response.

      ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      SOURCE CODE:
      ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      ImageRotation.java
      ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      import java.awt.RenderingHints;
      import java.awt.image.renderable.ParameterBlock;
      import java.io.BufferedInputStream;
      import java.io.BufferedOutputStream;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.InputStream;
      import java.io.OutputStream;
      import java.util.ArrayList;
      import java.util.List;
      import javax.media.jai.BorderExtenderConstant;
      import javax.media.jai.InterpolationBilinear;
      import javax.media.jai.JAI;
      import javax.media.jai.PlanarImage;
      import javax.media.jai.RenderedOp;
      import javax.media.jai.operator.TransposeDescriptor;
      import javax.media.jai.operator.TransposeType;

      import imageprocessing.RenameFileOutputStream;

      import com.sun.media.jai.codec.FileSeekableStream;
      import com.sun.media.jai.codec.ImageCodec;
      import com.sun.media.jai.codec.ImageEncoder;
      import com.sun.media.jai.codec.TIFFDecodeParam;
      import com.sun.media.jai.codec.TIFFDirectory;
      import com.sun.media.jai.codec.TIFFEncodeParam;

      public class ImageRotation {

      private final static File TMP_DIR = new File("Directory PATH");

      static {
      try {
      TMP_DIR.mkdirs();
      } catch (Exception e) {
      e.printStackTrace();
      System.out.println(" Error in creating directory : " + e.getMessage());
      }
      }

      public static void main(String[] args) {
      int rotationAngle = 90;

      if (rotationAngle == 0) {
      return;
      }

      File tempFile = null;
      File file = null;
      try {
      tempFile = copyTiffImage();
      file = new File("C:\\Users\\mpatel\\Downloads\\imagetest\\testRotation.tif");

      if (tempFile != null) {
      OutputStream out = null;
      try {
      out = getOutputStream1(file);
      writeRotatedTiffImage(tempFile, rotationAngle, out);
      } finally {
      if (out != null) {
      try {
      out.close();
      } catch (Exception ignore) {
      }
      }
      }
      }
      } catch (Exception e) {
      e.printStackTrace();
      System.out.println(" Error in Main method : " + e.getMessage());
      } finally {
      if (tempFile != null)
      tempFile.delete();
      }

      }

      private static File copyTiffImage() {
      OutputStream out = null;
      File tempFile = null;
      try {
      tempFile = File.createTempFile("FieldTicket", ".tif", null);
      out = new FileOutputStream(tempFile);
      readData(out);

      } catch (Exception e) {
      e.printStackTrace();
      System.out.println(" Error in copyTiffImage method : " + e.getMessage());
      } finally {
      if (out != null) {
      try {
      out.close();
      } catch (Exception ignore) {
      }
      }
      }
      return tempFile;
      }

      public static long readData(OutputStream out) {
      InputStream in = null;
      int nread;
      long total = 0;
      try {
      File f = new File(TMP_DIR, "testRotation.tif");
      in = new FileInputStream(f);
      in = new BufferedInputStream(in);

      byte buf[] = new byte[8191];
      while ((nread = in.read(buf)) != -1) {
      out.write(buf, 0, nread);
      total += nread;
      }
      } catch (Exception e) {
      e.printStackTrace();
      System.out.println(" Error in readData method : " + e.getMessage());
      } finally {
      if (in != null) {
      try {
      in.close();
      } catch (Exception ignore) {
      }
      }
      }
      return total;
      }

      private static void writeRotatedTiffImage(File tempFile, int rotationAngle, OutputStream os) throws Exception {
      try{
      FileSeekableStream stream = new FileSeekableStream(tempFile);

      TIFFDecodeParam tiffDecodeParam = new TIFFDecodeParam();
      ParameterBlock pb = new ParameterBlock();
      pb.add(stream);
      pb.add(tiffDecodeParam);

      ArrayList images = new ArrayList();
      long nextOffset = 0;
      do {
      RenderedOp op = JAI.create("tiff", pb);
      images.add(op);
      TIFFDirectory dir = (TIFFDirectory) op.getProperty("tiff_directory");
      nextOffset = dir.getNextIFDOffset();
      if (nextOffset != 0) {
      tiffDecodeParam.setIFDOffset(nextOffset);
      }
      } while (nextOffset != 0);

      TransposeType type;
      switch (rotationAngle) {
      case 90:
      type = TransposeDescriptor.ROTATE_90;
      break;
      case 180:
      type = TransposeDescriptor.ROTATE_180;
      break;
      case 270:
      type = TransposeDescriptor.ROTATE_270;
      break;
      default:
      throw new IllegalArgumentException("This rotation angle is not allowed: " + rotationAngle);
      }

      List transposedImages = new ArrayList(images.size() - 1);
      PlanarImage firstImage = transposeImage((PlanarImage) images.get(0), type);
      for (int i = 1; i < images.size(); i++) {
      PlanarImage newImage = transposeImage((PlanarImage) images.get(i), type);
      transposedImages.add(newImage);
      }

      TIFFEncodeParam tiffEncodeParam = new TIFFEncodeParam();
      tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_GROUP3_2D);
      tiffEncodeParam.setWriteTiled(false);
      tiffEncodeParam.setLittleEndian(false);

      ImageEncoder encoder = ImageCodec.createImageEncoder("TIFF", os, tiffEncodeParam);
      encoder.encode(firstImage);
      } catch (Exception e) {
      e.printStackTrace();
      System.out.println(" Error in writeRotatedTiffImage method : " + e.getMessage());
      }
      }

      private static PlanarImage transposeImage(PlanarImage img, TransposeType type) throws Exception {

      PlanarImage rotImg = null;
      try{
      /*ParameterBlock pb = new ParameterBlock();
      float angle = (float)Math.toRadians(90);
      pb.addSource(img); // The source image

      float centerX =img.getWidth()/2f;
      float centerY =img.getHeight()/2f;

      pb.add(centerX); // The x origin
      pb.add(centerY); // The y origin
      pb.add(angle); // The rotation angle

      //pb.add(Interpolation.getInstance(Interpolation.INTERP_NEAREST)); // The interpolation
      pb.add(new InterpolationBilinear());
      double[] constVal = { 1.0, 1.0, 1.0 };
      BorderExtenderConstant bE = new BorderExtenderConstant(constVal);
      RenderingHints hints = new RenderingHints(JAI.KEY_BORDER_EXTENDER, bE);
      rotImg = JAI.create("Rotate", pb, hints);*/

      ParameterBlock pb = new ParameterBlock();
      double[] constVal = { 1.0, 1.0, 1.0 };
      BorderExtenderConstant bE = new BorderExtenderConstant(constVal);
      RenderingHints hints = new RenderingHints(JAI.KEY_BORDER_EXTENDER, bE);
      pb.addSource(img);
      pb.add(type);
      //pb.add(Interpolation.getInstance(Interpolation.INTERP_NEAREST));
      pb.add(new InterpolationBilinear());

      rotImg = JAI.create("transpose", pb, hints);
      TIFFDecodeParam tiffDecodeParam = new TIFFDecodeParam();
      long nextOffset = 0;
      do {
      TIFFDirectory dir = (TIFFDirectory)rotImg.getProperty("tiff_directory");
      nextOffset = dir.getNextIFDOffset();
      if (nextOffset != 0) {
      tiffDecodeParam.setIFDOffset(nextOffset);
      }
      } while(nextOffset != 0);

      } catch (Exception e) {
      e.printStackTrace();
      System.out.println(" Error in transposeImage method : " + e.getMessage());
      }
      return rotImg;
      }

      public static OutputStream getOutputStream1(File file1) {
      return getOutputStream(file1);
      }

      private static OutputStream getOutputStream(File file) {
      OutputStream out = null;
      try {
      out = new BufferedOutputStream(RenameFileOutputStream.makeInstance(TMP_DIR, file));
      } catch (Exception e) {
      e.printStackTrace();
      System.out.println(" Error in getOutputStream method : " + e.getMessage());
      } finally {
      if (out != null) {
      try {
      out.close();
      } catch (Exception ignore) {
      }
      }
      }
      return out;
      }
      }

      -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      RenameFileOutputStream.java
      -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      public class RenameFileOutputStream extends FileOutputStream {

      File renameFrom;
      File renameTo;

      private RenameFileOutputStream(File renameFrom, File renameTo) throws IOException {
      super(renameFrom);
      this.renameFrom = renameFrom;
      this.renameTo = renameTo;
      }

      public static RenameFileOutputStream makeInstance(File tmpDir, File renameTo) throws IOException {
      return new RenameFileOutputStream(File.createTempFile("rnm", null, tmpDir), renameTo);
      }

      public void close() throws IOException {
      super.close();
      renameFrom.renameTo(renameTo);
      }
      }


      Thank You,
      Mayank
        • 1. Re: Error saving Rotated image using JAI
          684462
          This has been resolved. I was receiving 8 Pixel Image, which could not compress with Group 3 or 4.

          Better way to perform Image transformation is: First create Temporary file and perform operation on it and then create InputStream of temp file and write it down on original. After that you can delete temp file. This way it's less chances to corrupt original image file.

          Compression should be like this:
          int pixelSize = img.getColorModel().getPixelSize();
          if (1 == pixelSize) {
          tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_GROUP3_2D);
          } else if (8 == pixelSize) {
          tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_DEFLATE);
          } else if (24 == pixelSize) {
          tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_JPEG_TTN2);
          }

          Thanks,

          Edited by: Mayank on Oct 21, 2011 8:33 PM