Add lock while uploading image file

pull/296/head
johnniang 2019-09-10 12:02:42 +08:00
parent 8189cc08dd
commit 7aaf670276
4 changed files with 34 additions and 100 deletions

View File

@ -55,6 +55,7 @@ ext {
dataformatYamlVersion = '2.9.2'
jgitVersion = '5.3.0.201903130848-r'
flexmarkVersion = '0.42.12'
thumbnailatorVersion = '0.4.8'
}
dependencies {
@ -94,6 +95,8 @@ dependencies {
implementation "com.vladsch.flexmark:flexmark-ext-yaml-front-matter:$flexmarkVersion"
implementation "com.vladsch.flexmark:flexmark-html-parser:$flexmarkVersion"
implementation "net.coobird:thumbnailator:$thumbnailatorVersion"
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'

View File

@ -1,6 +1,7 @@
package run.halo.app.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
@ -36,6 +37,7 @@ import java.security.NoSuchAlgorithmException;
*/
@Configuration
@EnableConfigurationProperties(HaloProperties.class)
@Slf4j
public class HaloConfiguration {
private final static int TIMEOUT = 5000;

View File

@ -1,6 +1,7 @@
package run.halo.app.handler.file;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
@ -13,8 +14,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;
@ -22,6 +23,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Calendar;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
@ -46,15 +48,15 @@ public class LocalFileHandler implements FileHandler {
/**
* Thumbnail width.
*/
@Deprecated
private final static int THUMB_WIDTH = 256;
/**
* Thumbnail height.
*/
@Deprecated
private final static int THUMB_HEIGHT = 256;
ReentrantLock lock = new ReentrantLock();
private final OptionService optionService;
private final String workDir;
@ -141,25 +143,27 @@ public class LocalFileHandler implements FileHandler {
// Check file type
if (FileHandler.isImageType(uploadResult.getMediaType()) && !isSvg) {
// Upload a thumbnail
String thumbnailBasename = basename + THUMBNAIL_SUFFIX;
String thumbnailSubFilePath = subDir + thumbnailBasename + '.' + extension;
Path thumbnailPath = Paths.get(workDir + thumbnailSubFilePath);
lock.lock();
try {
// Upload a thumbnail
String thumbnailBasename = basename + THUMBNAIL_SUFFIX;
String thumbnailSubFilePath = subDir + thumbnailBasename + '.' + extension;
Path thumbnailPath = Paths.get(workDir + thumbnailSubFilePath);
// Create the thumbnail
Files.createFile(thumbnailPath);
// Read as image
BufferedImage originalImage = ImageIO.read(uploadPath.toFile());
// Read as image
BufferedImage originalImage = ImageUtils.readImage(uploadPath.toFile());
// Generate thumbnail
generateThumbnail(originalImage, thumbnailPath, extension);
// Generate thumbnail
generateThumbnail(originalImage, thumbnailPath, extension);
// Set width and height
uploadResult.setWidth(originalImage.getWidth());
uploadResult.setHeight(originalImage.getHeight());
// Set thumb path
uploadResult.setThumbPath(thumbnailSubFilePath);
// Set width and height
uploadResult.setWidth(originalImage.getWidth());
uploadResult.setHeight(originalImage.getHeight());
// Set thumb path
uploadResult.setThumbPath(thumbnailSubFilePath);
} finally {
lock.unlock();
}
} else {
uploadResult.setThumbPath(subFilePath);
}
@ -216,13 +220,14 @@ public class LocalFileHandler implements FileHandler {
Assert.notNull(originalImage, "Image must not be null");
Assert.notNull(thumbPath, "Thumb path must not be null");
// Create the thumbnail
Files.createFile(thumbPath);
// Convert to thumbnail and copy the thumbnail
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());
Thumbnails.of(originalImage).size(THUMB_WIDTH, THUMB_HEIGHT).keepAspectRatio(true).toFile(thumbPath.toFile());
log.debug("Generated thumbnail image, and wrote the thumbnail to [{}]", thumbPath.toString());
}
}

View File

@ -1,76 +0,0 @@
package run.halo.app.utils;
import com.google.common.io.Files;
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() {
ImageIO.setUseCache(true);
ImageIO.setCacheDirectory(Files.createTempDir());
}
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<ImageWriter> 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();
}
}