12 Replies Latest reply: Jan 15, 2011 8:28 AM by 831465 RSS

    Image resizing using JAI

    843802
      Image resizing using JAI

      We have next algorithm of resizing:
              RenderedOp image;
              try {
                  SeekableStream s = SeekableStream.wrapInputStream(is, true);
                  image = JAI.create("stream", s);
                  ((OpImage) image.getRendering()).setTileCache(null);
      
                  double resizeFactor = getResizeFactor(width, height, image
                          .getWidth(), image.getHeight());
                  if (resizeFactor < 1) {
                      image = JAI.create("SubsampleAverage", image, resizeFactor,
                              resizeFactor, QUALITY_HINTS);
                  } else if (resizeFactor > 1) {
                      image = ScaleDescriptor.create(image, (float) resizeFactor,
                              (float) resizeFactor, 0.0f, 0.0f, Interpolation
                                      .getInstance(Interpolation.INTERP_BICUBIC),
                              null);
                  }
      
                  try {
                      ByteArrayOutputStream os = new ByteArrayOutputStream();
                      try {
                          ImageIO.write(image, "png", os);
                          return os.toByteArray();
                      } finally {
                          os.close();
                      }
                  } catch (IOException e) {
                      throw new RuntimeException(e);
                  }
              } finally {
                  is.close();
              }
      Source without resizing: http://www.servit.ch/sites/all/themes/servit_oss/logo.png
      Resize example #1: http://208.109.126.120:7080/gdesk-web/thumbnail/1123_148x148.png (you may see cutted bottom edge)
      Resize example #2: http://208.109.126.120:7080/gdesk-web/thumbnail/1123_30x30.png (you may see cutted bottom and right edges and artifacts at left and top)

      This resizing algorithm works perfect, BUT he cuts 1-2 pixels from bottom edge and 1-2 pixels from right edge AND adds artifacts to the left and top edges. What I can do with artefacts and cutted pixels, how I can take them back???
        • 1. Re: Image resizing using JAI
          843802
          Wrong urls in first post. New URLs

          http://208.109.126.120:7080/gdesk-web/thumbnail/1126_148x148.png
          http://208.109.126.120:7080/gdesk-web/thumbnail/1126_30x30.png
          • 2. Re: Image resizing using JAI
            843802
            Hm... I cant reproduce that behavior. What are your QUALITY_HINTS?
            • 3. Re: Image resizing using JAI
              843802
              Thanks for answer!
              RenderingHints QUALITY_HINTS = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
              • 4. Re: Image resizing using JAI
                843802
                Did you tried my image??
                • 5. Re: Image resizing using JAI
                  843802
                  I really can't reproduce it. When I run the code below, I get a 148x148 image.
                  import javax.swing.*;
                  import javax.media.jai.*;
                  import java.awt.RenderingHints;
                  import java.net.URL;
                  public class SSCCE {
                      public static void main(String[] args) throws Exception{
                          RenderedOp image = JAI.create("url",
                                  new URL("http://www.servit.ch/sites/all/themes/servit_oss/logo.png"),
                                  null,null);
                  
                          RenderingHints QUALITY_HINTS = new RenderingHints(
                                  RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                          image = JAI.create("SubsampleAverage",image,.78,.78,QUALITY_HINTS);
                          System.out.println(image.getWidth() + "x" + image.getWidth());
                          
                          JFrame frame = new JFrame();
                          frame.setLayout(new java.awt.GridBagLayout());
                          frame.add(new com.sun.media.jai.widget.DisplayJAI(image));
                          frame.setSize(300,300);
                          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                          frame.setVisible(true);
                      }
                  }
                  In fact, when I run this I get a somewhat blury image. I don't get the crisp image you're getting. This is kind a suprising since I know SubsampleAverage to be of decent quality. Maybe there are some bugs.
                  • 6. Re: Image resizing using JAI
                    843802
                    I tested your class and I found that you are right :)

                    And I think that problem in
                    ImageIO.write(image, "png", os);
                    I used another method:
                            RenderedOp image;
                            try {
                                // 1) Read image into memory
                                SeekableStream s = SeekableStream.wrapInputStream(is, true);
                                image = JAI.create("stream", s);
                                ((OpImage) image.getRendering()).setTileCache(null);
                    
                                // 2) Resize image
                                double resizeFactor = getResizeFactor(width, height, image
                                        .getWidth(), image.getHeight());
                                if (true) {
                                    image = JAI.create("SubsampleAverage", image, resizeFactor,
                                            resizeFactor, QUALITY_HINTS);
                                    PNGEncodeParam.RGB pngEncodeParam = new PNGEncodeParam.RGB();
                                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                    ImageEncoder encoder = ImageCodec.createImageEncoder("PNG",
                                            outputStream, pngEncodeParam);
                                    PlanarImage planarImage = image.getRendering();
                                    encoder.encode(planarImage);
                                    return outputStream.toByteArray();
                                } else if (resizeFactor > 1) {
                                    image = ScaleDescriptor.create(image, (float) resizeFactor,
                                            (float) resizeFactor, 0.0f, 0.0f, Interpolation
                                                    .getInstance(Interpolation.INTERP_BICUBIC),
                                            null);
                                }
                    
                                // 3) Convert image to PNG
                                return convertImage(image);
                            } finally {
                                is.close();
                            }
                    I changed
                    ImageIO.write(image, "png", os);
                    to
                                    PNGEncodeParam.RGB pngEncodeParam = new PNGEncodeParam.RGB();
                                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                    ImageEncoder encoder = ImageCodec.createImageEncoder("PNG",
                                            outputStream, pngEncodeParam);
                                    PlanarImage planarImage = image.getRendering();
                                    encoder.encode(planarImage);
                                    return outputStream.toByteArray();
                    And seems it helps, BUT now I have another problem - black bottom border.
                    • 7. Re: Image resizing using JAI
                      843802
                      Dear Maxideon,

                      I changed resize factor at your sample and I get black edge at the bottom of the image.
                      import javax.swing.*;
                      import javax.media.jai.*;
                      
                      import java.awt.RenderingHints;
                      import java.net.URL;
                      
                      public class SSCCE {
                          public static void main(String[] args) throws Exception {
                              RenderedOp image = JAI.create("url", new URL(
                                      "http://208.109.126.120:7080/gdesk-web/resource/1126"), null,
                                      null);
                      
                                  RenderingHints QUALITY_HINTS = new RenderingHints(
                                          RenderingHints.KEY_RENDERING,
                                          RenderingHints.VALUE_RENDER_QUALITY);
                                  double rf = 110d / 360d;
                                  RenderedOp simage = JAI
                                          .create("SubsampleAverage", image, rf, rf, QUALITY_HINTS);
                                  System.out.println(image.getWidth() + "x" + image.getWidth());
                      
                                  JFrame frame = new JFrame();
                                  frame.setLayout(new java.awt.GridBagLayout());
                                  frame.add(new com.sun.media.jai.widget.DisplayJAI(simage));
                                  frame.setSize(300, 300);
                                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                  frame.setVisible(true);
                          }
                      }
                      If you know how to remove this black line or make it white or other solution, please say me.
                      • 8. Re: Image resizing using JAI
                        843802
                        I have had problems with resizing with ImageIO. Have you tried the "Scale" operator? I think thats meant for resizing ops.

                        Edited by: rpandit24 on Feb 5, 2010 8:00 AM
                        • 9. Re: Image resizing using JAI
                          843802
                          Yes we tried to use "Scale", but "SubsampleAverage" gives more better results.
                          • 10. Re: Image resizing using JAI
                            843802
                            I have changed my code which makes image convertation and now I have other problem.
                            I have black line at bottom of the image after resizing. Did anyone knows how to fix it.
                            You find image with black edge here http://208.109.126.120:7080/gdesk-web/thumbnail/1126_148x148.png

                            I need any help.

                            Converting to PNG:
                                        PNGEncodeParam.RGB pngEncodeParam = new PNGEncodeParam.RGB();
                                        pngEncodeParam.setBackgroundRGB(new int[] { 255, 255, 255 });
                                        pngEncodeParam.setTransparentRGB(new int[] { 255, 255, 255 });
                             
                                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                        ImageEncoder encoder = ImageCodec.createImageEncoder("PNG",
                                                outputStream, pngEncodeParam);
                                        PlanarImage planarImage = scaledImage.getNewRendering();
                                        encoder.encode(planarImage);
                            • 11. Re: Image resizing using JAI
                              843802
                              I'm having the same issue right now with a black line at the bottom of a resized image. I have concluded that this line is created becuase the resizing of the image is slightly off, probably by just 1 pixel. Maybe from a rounding error.

                              The image is also slightly blurry, as if the resizing is off.

                              I am trying to find out more about setting specific resizing amounts instead of using a percentage.
                              • 12. Re: Image resizing using JAI
                                831465
                                only use this for final scale factory

                                double width = source.getWidth() * xScale;
                                xScale = xScale * Math.round(width) / width;
                                double height = source.getHeight() * yScale;
                                yScale = yScale * Math.round(height) / height;