diff --git a/src/main/java/run/halo/app/handler/file/LocalFileHandler.java b/src/main/java/run/halo/app/handler/file/LocalFileHandler.java index dbd65be22..9937cee72 100644 --- a/src/main/java/run/halo/app/handler/file/LocalFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/LocalFileHandler.java @@ -1,9 +1,7 @@ package run.halo.app.handler.file; -import cn.hutool.core.img.ImgUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; -import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.web.multipart.MultipartFile; @@ -15,8 +13,8 @@ import run.halo.app.model.support.UploadResult; import run.halo.app.service.OptionService; import run.halo.app.utils.FilenameUtils; import run.halo.app.utils.HaloUtils; +import run.halo.app.utils.ImageUtils; -import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.IOException; import java.nio.file.Files; @@ -151,15 +149,15 @@ public class LocalFileHandler implements FileHandler { // Create the thumbnail Files.createFile(thumbnailPath); - // Generate thumbnail - generateThumbnail(uploadPath, thumbnailPath); - // Read as image - BufferedImage image = ImageIO.read(Files.newInputStream(uploadPath)); + BufferedImage originalImage = ImageUtils.readImage(uploadPath.toFile()); + + // Generate thumbnail + generateThumbnail(originalImage, thumbnailPath, extension); // Set width and height - uploadResult.setWidth(image.getWidth()); - uploadResult.setHeight(image.getHeight()); + uploadResult.setWidth(originalImage.getWidth()); + uploadResult.setHeight(originalImage.getHeight()); // Set thumb path uploadResult.setThumbPath(thumbnailSubFilePath); } else { @@ -213,21 +211,18 @@ public class LocalFileHandler implements FileHandler { return AttachmentType.LOCAL.equals(type); } - /** - * Generates thumbnail image. - * - * @param imagePath image path must not be null - * @param thumbPath thumbnail path must not be null - * @throws IOException throws if image provided is not valid - */ - private void generateThumbnail(@NonNull Path imagePath, @NonNull Path thumbPath) throws IOException { - Assert.notNull(imagePath, "Image path must not be null"); + + private void generateThumbnail(BufferedImage originalImage, Path thumbPath, String extension) throws IOException { + Assert.notNull(originalImage, "Image must not be null"); Assert.notNull(thumbPath, "Thumb path must not be null"); - log.info("Generating thumbnail: [{}] for image: [{}]", thumbPath.getFileName(), imagePath.getFileName()); - // Convert to thumbnail and copy the thumbnail - ImgUtil.scale(imagePath.toFile(), thumbPath.toFile(), 0.1f); + log.debug("Trying to generate thumbnail: [{}]", thumbPath.toString()); + log.debug("Got original image"); + log.debug("Generating thumbnail image, and trying to write the thumbnail to [{}]", thumbPath.toString()); + ImageUtils.compress(originalImage, 0.1f, Files.newOutputStream(thumbPath)); + log.debug("Wrote thumbnail to [{}]", thumbPath.toString()); } + } diff --git a/src/main/java/run/halo/app/utils/ImageUtils.java b/src/main/java/run/halo/app/utils/ImageUtils.java new file mode 100644 index 000000000..6c7ec857b --- /dev/null +++ b/src/main/java/run/halo/app/utils/ImageUtils.java @@ -0,0 +1,73 @@ +package run.halo.app.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.Assert; + +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.Iterator; + +/** + * ImageUtils. + * + * @author johnniang + */ +@Slf4j +public class ImageUtils { + + private ImageUtils() { + } + + + public static void writeImage(BufferedImage image, String filepath, String extension) throws IOException { + File file = new File(filepath); + + ImageIO.write(image, extension, file); + } + + public static BufferedImage readImage(File file) throws IOException { + Assert.notNull(file, "file must not be null"); + + return ImageIO.read(file); + } + + public static BufferedImage readImage(InputStream inputStream) throws IOException { + Assert.notNull(inputStream, "input stream must not be null"); + + return ImageIO.read(inputStream); + } + + public static BufferedImage readImage(byte[] buf) throws IOException { + Assert.notNull(buf, "image byte array must not be null"); + + + return ImageIO.read(new ByteArrayInputStream(buf)); + } + + public static void compress(BufferedImage originalImage, float quantity, OutputStream os) throws IOException { + Assert.notNull(originalImage, "original image must not be null"); + + Iterator imageWriterIterator = ImageIO.getImageWritersByFormatName("jpg"); + + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(os); + + ImageWriter imageWriter = imageWriterIterator.next(); + imageWriter.setOutput(imageOutputStream); + + ImageWriteParam param = imageWriter.getDefaultWriteParam(); + + if (param.canWriteCompressed()) { + param.setCompressionMode((ImageWriteParam.MODE_EXPLICIT)); + param.setCompressionQuality(quantity); + } + + imageWriter.write(null, new IIOImage(originalImage, null, null), param); + + imageWriter.dispose(); + } +}