Improve SVG preview generation

This commit is contained in:
ViacheslavKlimov 2023-12-15 16:20:25 +02:00
parent 61aa595b20
commit 3ac71e9ff1

View File

@ -20,8 +20,10 @@ import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.With;
import lombok.extern.slf4j.Slf4j;
import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.bridge.BridgeContext;
@ -121,7 +123,7 @@ public class ImageUtils {
image.setHeight(bufferedImage.getHeight());
ProcessedImage preview = new ProcessedImage();
int[] thumbnailDimensions = getThumbnailDimensions(image.getWidth(), image.getHeight(), thumbnailMaxDimension);
int[] thumbnailDimensions = getThumbnailDimensions(image.getWidth(), image.getHeight(), thumbnailMaxDimension, true);
preview.setWidth(thumbnailDimensions[0]);
preview.setHeight(thumbnailDimensions[1]);
@ -191,8 +193,18 @@ public class ImageUtils {
image.setSize(data.length);
PNGTranscoder transcoder = new PNGTranscoder();
transcoder.addTranscodingHint(PNGTranscoder.KEY_MAX_WIDTH, (float) thumbnailMaxDimension);
transcoder.addTranscodingHint(PNGTranscoder.KEY_MAX_HEIGHT, (float) thumbnailMaxDimension);
if (image.getSize() < 10240) { // if SVG is smaller than 10kB (average 250x250 PNG preview size)
return withPreviewAsOriginalImage(image);
} else if (image.getSize() > 102400 && image.getWidth() != 0) { // considering SVG image detailed after 100kB
// increasing preview dimensions
thumbnailMaxDimension = 512;
int[] thumbnailDimensions = getThumbnailDimensions(image.getWidth(), image.getHeight(), thumbnailMaxDimension, false);
transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) thumbnailDimensions[0]);
transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) thumbnailDimensions[1]);
} else {
transcoder.addTranscodingHint(PNGTranscoder.KEY_MAX_WIDTH, (float) thumbnailMaxDimension);
transcoder.addTranscodingHint(PNGTranscoder.KEY_MAX_HEIGHT, (float) thumbnailMaxDimension);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
transcoder.transcode(new TranscoderInput(new ByteArrayInputStream(data)), new TranscoderOutput(out));
byte[] pngThumbnail = out.toByteArray();
@ -214,18 +226,16 @@ public class ImageUtils {
image.setSize(data.length);
image.setWidth(0);
image.setHeight(0);
ProcessedImage preview = new ProcessedImage();
preview.setMediaType(mediaType);
preview.setData(null);
preview.setSize(data.length);
preview.setWidth(0);
preview.setHeight(0);
image.setPreview(preview);
return image;
return withPreviewAsOriginalImage(image);
}
private static int[] getThumbnailDimensions(int originalWidth, int originalHeight, int maxDimension) {
if (originalWidth <= maxDimension && originalHeight <= maxDimension) {
public static ProcessedImage withPreviewAsOriginalImage(ProcessedImage originalImage) {
originalImage.setPreview(originalImage.withData(null));
return originalImage;
}
private static int[] getThumbnailDimensions(int originalWidth, int originalHeight, int maxDimension, boolean originalIfSmaller) {
if (originalWidth <= maxDimension && originalHeight <= maxDimension && originalIfSmaller) {
return new int[]{originalWidth, originalHeight};
}
int thumbnailWidth;
@ -242,10 +252,13 @@ public class ImageUtils {
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class ProcessedImage {
private String mediaType;
private int width;
private int height;
@With
private byte[] data;
private long size;
private ProcessedImage preview;