Re-sizing an image without losing quality

前端 未结 9 1417
温柔的废话
温柔的废话 2020-11-29 01:45

I made this code to resize images with two factors. It works, but the quality of image is very bad after it is resized! Can you help me?

This is the code

<         


        
9条回答
  •  时光取名叫无心
    2020-11-29 02:25

    The following code produced me highest quality resize with aspect ratio preserved. Tried few things and read several entries presented here in other answers. Lost two days and in the end I got the best result with plain Java method (tried also ImageMagick and java-image-scaling libraries):

    public static boolean resizeUsingJavaAlgo(String source, File dest, int width, int height) throws IOException {
      BufferedImage sourceImage = ImageIO.read(new FileInputStream(source));
      double ratio = (double) sourceImage.getWidth()/sourceImage.getHeight();
      if (width < 1) {
        width = (int) (height * ratio + 0.4);
      } else if (height < 1) {
        height = (int) (width /ratio + 0.4);
      }
    
      Image scaled = sourceImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
      BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null), scaled.getHeight(null), BufferedImage.TYPE_INT_RGB);
      Graphics2D g2d = bufferedScaled.createGraphics();
      g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
      g2d.drawImage(scaled, 0, 0, width, height, null);
      dest.createNewFile();
      writeJpeg(bufferedScaled, dest.getCanonicalPath(), 1.0f);
      return true;
    }
    
    
    /**
    * Write a JPEG file setting the compression quality.
    *
    * @param image a BufferedImage to be saved
    * @param destFile destination file (absolute or relative path)
    * @param quality a float between 0 and 1, where 1 means uncompressed.
    * @throws IOException in case of problems writing the file
    */
    private static void writeJpeg(BufferedImage image, String destFile, float quality)
          throws IOException {
      ImageWriter writer = null;
      FileImageOutputStream output = null;
      try {
        writer = ImageIO.getImageWritersByFormatName("jpeg").next();
        ImageWriteParam param = writer.getDefaultWriteParam();
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(quality);
        output = new FileImageOutputStream(new File(destFile));
        writer.setOutput(output);
        IIOImage iioImage = new IIOImage(image, null, null);
        writer.write(null, iioImage, param);
      } catch (IOException ex) {
        throw ex;
      } finally {
        if (writer != null) {
          writer.dispose();
        }
        if (output != null) {
          output.close();
        }
      }
    }
    

提交回复
热议问题