I. Description of premises

Service requirements require a wave of compression of images before uploading them to the server. Requirements: keep the picture size, occupied memory compression

Note: all kinds of similar articles on the Internet are basically repeated, with few resources and the contents of many articles can not achieve the effect of corresponding explanation. From the beginning of development to now has been facing Baidu programming, in the spirit of drinking water to think about the source of psychology, remember this pit, as well as their own way of processing.

Two, several ways to achieve compression at present

1.Thumbnailator (recommended)

1.1 introduction

Thumbnailator is a Java class library for generating image thumbnails, either from very simple code or directly from a whole directory of images.

Support: Picture scaling, region cropping, watermark, rotation, keep scale, picture compression. Thumbnailator website: code.google.com/p/thumbnail…

< the dependency > < groupId > net. Coobird < / groupId > < artifactId > thumbnailator < / artifactId > < version > [0.4, < / version 0.5) > < / dependency >Copy the code

The website the latest version for 0.4.11 (record the current time: 2020/07/22) Thumbnailator document address: coobird. Making. IO/thumbnailat…

1.2 the use of

Public class ImageUtils {/** ** compress image according to the specified size ** @param imageBytes source image byte array * @param desFileSize specify the image size, Unit: KB * @param imageId imageId * @returnPublic static byte[] compressPicForScale(byte[] imageBytes, long desFileSize, String imageId, Double quality) {if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
      return imageBytes;
    }
    long srcSize = imageBytes.length;
    try {
      ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
      ByteArrayOutputStream outputStream= new ByteArrayOutputStream(imageBytes.length);
      Thumbnails.of(inputStream).scale(1f).outputQuality(quality).toOutputStream(outputStream);
      imageBytes = outputStream.toByteArray();
      log.info(
          "[image compression] imageId = {} = {} KB | | image the original size compressed size = {} KB",
          imageId,
          srcSize / 1024,
          imageBytes.length / 1024);
    } catch (Exception e) {
      log.error("MSG = image compression failed!", e);
    }
    returnimageBytes; }}Copy the code

Scale () specifies the size of the image, while size() specifies the width and height of the image. OutputQuality Specifies the image quality. 2. The actual measurement proves that no matter which kind of compression, the support strength of JPG format is the best. So if there is no format requirement, please convert to JPG format. Especially PNG format please must turn! 3. In the above method, when outputting the image, the final image will be about 30% larger than the size printed in the log, byte[], which is speculated to be caused by compressed space debris.

1.3 Description of deep pits

Key !!!!! Don’t do loop calls!! There is a fixed algorithm for quality compression, when the size is fixed and there is no outputQuality(0.9), the next cycle quality will become 0.81!! The loop can only lead to one result: pro, endless loop ~

For example: loop calls cause an infinite loop, also picked up in a blog. The drainage gains…

2. Java native API (quite a pit, the quality coefficient setting is small, but the size will be larger. Just take a look.)

2.1 the code

public static boolean compressPic(String srcFilePath, String descFilePath) throws IOException { File file = null; BufferedImage src = null; FileOutputStream out = null; ImageWriter imgWrier; ImageWriteParam imgWriteParams; / / specified write picture for JPG imgWrier = ImageIO. The getImageWritersByFormatName (" JPG "). The next (); imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam( null); / / to use compression, must specify the compression method for MODE_EXPLICIT imgWriteParams. SetCompressionMode (imgWriteParams. MODE_EXPLICIT); / / specify the degree of compression here, within the scope of parameters determination qality is 0 ~ 1, imgWriteParams. SetCompressionQuality ((float), 1); imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED); ColorModel colorModel = ImageIO.read(new File(srcFilePath)).getColorModel(); // ColorModel.getRGBdefault(); / / specified color model used in compression / / imgWriteParams setDestinationType (new javax.mail. Imageio. ImageTypeSpecifier (/ / colorModel, colorModel.createCompatibleSampleModel(16, 16))); imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier( colorModel, colorModel.createCompatibleSampleModel(16, 16))); try { if (isBlank(srcFilePath)) { return false; } else { file = new File(srcFilePath); System.out.println(file.length()); src = ImageIO.read(file); out = new FileOutputStream(descFilePath); imgWrier.reset(); // The out value must be specified. To call the write method, ImageOutputStream can pass any / / OutputStream tectonic imgWrier setOutput (ImageIO. CreateImageOutputStream (out)); ImgWrier. Write (null, new IIOImage(SRC, null, null), imgWriteParams); out.flush(); out.close(); } } catch (Exception e) { e.printStackTrace(); return false; } return true; } public static boolean isBlank(String string) { if (string == null || string.length() == 0 || string.trim().equals(""))  { return true; } return false; }Copy the code

3. Summary

1. In fact, there should be no giant god pit products, the need to cycle down to a fixed size is not bullshit. Analysis ah, such as a 5M photo, the same format under the circumstances of 500K pressure, this picture can still see? Compressing images is all about efficiency. In my personal tests, a compression factor of 0.5 did not cause significant distortion, and anything below that was dangerous. In this case, if the product doesn’t think it will work, it will probably have to go to war, haha. 2. Ending: When PNG is converted to JPG, color distortion may occur. This can be done by using the drawing Tool to create a blank scroll the size of the original image, and then placing the image you want to convert into it. Principle does not understand ~ a bit metaphysical.