Compare commits
No commits in common. "537677abf765a35143c94be8a0d57d1fb6ba1125" and "ee808c768d4fad152d0cd91f481ae6d8292382bc" have entirely different histories.
537677abf7
...
ee808c768d
@ -102,14 +102,15 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly 'org.jetbrains:annotations:26.0.2-1'
|
compileOnly 'org.jetbrains:annotations:26.0.2-1'
|
||||||
|
|
||||||
|
// https://mvnrepository.com/artifact/com.twelvemonkeys.imageio/imageio-webp
|
||||||
|
runtimeOnly 'com.twelvemonkeys.imageio:imageio-webp:3.12.0'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.twelvemonkeys.imageio/imageio-batik
|
// https://mvnrepository.com/artifact/com.twelvemonkeys.imageio/imageio-batik
|
||||||
runtimeOnly 'com.twelvemonkeys.imageio:imageio-batik:3.12.0'
|
runtimeOnly 'com.twelvemonkeys.imageio:imageio-batik:3.12.0'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-all
|
// https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-all
|
||||||
runtimeOnly 'org.apache.xmlgraphics:batik-all:1.19'
|
runtimeOnly 'org.apache.xmlgraphics:batik-all:1.19'
|
||||||
|
|
||||||
implementation 'com.drewnoakes:metadata-extractor:2.19.0'
|
|
||||||
|
|
||||||
// Custom testing
|
// Custom testing
|
||||||
testImplementation 'org.testcontainers:testcontainers:1.21.4'
|
testImplementation 'org.testcontainers:testcontainers:1.21.4'
|
||||||
testImplementation 'org.testcontainers:junit-jupiter:1.21.4'
|
testImplementation 'org.testcontainers:junit-jupiter:1.21.4'
|
||||||
|
|||||||
Binary file not shown.
@ -7,14 +7,6 @@ import app.mealsmadeeasy.api.user.User;
|
|||||||
import app.mealsmadeeasy.api.util.MimeTypeService;
|
import app.mealsmadeeasy.api.util.MimeTypeService;
|
||||||
import app.mealsmadeeasy.api.util.NoSuchEntityWithIdException;
|
import app.mealsmadeeasy.api.util.NoSuchEntityWithIdException;
|
||||||
import app.mealsmadeeasy.api.util.NoSuchEntityWithUsernameAndFilenameException;
|
import app.mealsmadeeasy.api.util.NoSuchEntityWithUsernameAndFilenameException;
|
||||||
import com.drew.imaging.ImageMetadataReader;
|
|
||||||
import com.drew.imaging.ImageProcessingException;
|
|
||||||
import com.drew.metadata.Directory;
|
|
||||||
import com.drew.metadata.Metadata;
|
|
||||||
import com.drew.metadata.MetadataException;
|
|
||||||
import com.drew.metadata.jpeg.JpegDirectory;
|
|
||||||
import com.drew.metadata.png.PngDirectory;
|
|
||||||
import com.drew.metadata.webp.WebpDirectory;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@ -111,33 +103,6 @@ public class S3ImageService implements ImageService {
|
|||||||
return didTransfer;
|
return didTransfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record HeightWidth(int height, int width) {}
|
|
||||||
|
|
||||||
private <D extends Directory> HeightWidth getHeightAndWidthFromMetadata(
|
|
||||||
InputStream inputStream,
|
|
||||||
Class<D> directoryClass,
|
|
||||||
int heightTag,
|
|
||||||
int widthTag,
|
|
||||||
String debugName
|
|
||||||
) throws IOException {
|
|
||||||
try {
|
|
||||||
final Metadata metadata = ImageMetadataReader.readMetadata(inputStream);
|
|
||||||
final D directory = metadata.getFirstDirectoryOfType(directoryClass);
|
|
||||||
if (directory == null) {
|
|
||||||
throw new RuntimeException("Unable to get " + directoryClass.getSimpleName() + " for " + debugName);
|
|
||||||
}
|
|
||||||
if (!directory.containsTag(heightTag)) {
|
|
||||||
throw new RuntimeException("Unable to find height tag for " + debugName);
|
|
||||||
}
|
|
||||||
if (!directory.containsTag(widthTag)) {
|
|
||||||
throw new RuntimeException("Unable to find width tag for " + debugName);
|
|
||||||
}
|
|
||||||
return new HeightWidth(directory.getInt(heightTag), directory.getInt(widthTag));
|
|
||||||
} catch (ImageProcessingException | MetadataException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiNote Consumes and closes the {@link java.io.InputStream}.
|
* @apiNote Consumes and closes the {@link java.io.InputStream}.
|
||||||
*
|
*
|
||||||
@ -172,43 +137,15 @@ public class S3ImageService implements ImageService {
|
|||||||
this.imageBucketName, filename, mimeType, toStore, objectSize
|
this.imageBucketName, filename, mimeType, toStore, objectSize
|
||||||
);
|
);
|
||||||
|
|
||||||
final HeightWidth hw;
|
|
||||||
switch (mimeType) {
|
|
||||||
case "image/jpeg" -> {
|
|
||||||
hw = this.getHeightAndWidthFromMetadata(
|
|
||||||
toRead,
|
|
||||||
JpegDirectory.class,
|
|
||||||
JpegDirectory.TAG_IMAGE_HEIGHT,
|
|
||||||
JpegDirectory.TAG_IMAGE_WIDTH,
|
|
||||||
userFilename
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "image/png" -> {
|
|
||||||
hw = this.getHeightAndWidthFromMetadata(
|
|
||||||
toRead,
|
|
||||||
PngDirectory.class,
|
|
||||||
PngDirectory.TAG_IMAGE_HEIGHT,
|
|
||||||
PngDirectory.TAG_IMAGE_WIDTH,
|
|
||||||
userFilename
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "image/webp" -> {
|
|
||||||
hw = this.getHeightAndWidthFromMetadata(
|
|
||||||
toRead,
|
|
||||||
WebpDirectory.class,
|
|
||||||
WebpDirectory.TAG_IMAGE_HEIGHT,
|
|
||||||
WebpDirectory.TAG_IMAGE_WIDTH,
|
|
||||||
userFilename
|
|
||||||
);
|
|
||||||
}
|
|
||||||
case "image/svg+xml" -> {
|
|
||||||
final BufferedImage bufferedImage = ImageIO.read(toRead);
|
final BufferedImage bufferedImage = ImageIO.read(toRead);
|
||||||
hw = new HeightWidth(bufferedImage.getHeight(), bufferedImage.getWidth());
|
if (bufferedImage == null) {
|
||||||
|
throw new ImageException(
|
||||||
|
ImageException.Type.UNSUPPORTED_IMAGE_TYPE,
|
||||||
|
"ImageIO could not read image: " + userFilename
|
||||||
|
);
|
||||||
}
|
}
|
||||||
default -> throw new RuntimeException("Unsupported mime type: " + mimeType);
|
final int height = bufferedImage.getHeight();
|
||||||
}
|
final int width = bufferedImage.getWidth();
|
||||||
final int height = hw.height();
|
|
||||||
final int width = hw.width();
|
|
||||||
|
|
||||||
toRead.close();
|
toRead.close();
|
||||||
toStore.close();
|
toStore.close();
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public class MimeTypeService {
|
|||||||
final Matcher m = extensionPattern.matcher(userFilename);
|
final Matcher m = extensionPattern.matcher(userFilename);
|
||||||
if (m.matches()) {
|
if (m.matches()) {
|
||||||
final String extension = m.group(1);
|
final String extension = m.group(1);
|
||||||
return switch (extension.toLowerCase()) {
|
return switch (extension) {
|
||||||
case "jpg", "jpeg" -> IMAGE_JPEG;
|
case "jpg", "jpeg" -> IMAGE_JPEG;
|
||||||
case "png" -> IMAGE_PNG;
|
case "png" -> IMAGE_PNG;
|
||||||
case "svg" -> IMAGE_SVG;
|
case "svg" -> IMAGE_SVG;
|
||||||
@ -32,7 +32,7 @@ public class MimeTypeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getExtension(String mimeType) {
|
public String getExtension(String mimeType) {
|
||||||
return switch (mimeType.toLowerCase()) {
|
return switch (mimeType) {
|
||||||
case IMAGE_JPEG -> "jpg";
|
case IMAGE_JPEG -> "jpg";
|
||||||
case IMAGE_PNG -> "png";
|
case IMAGE_PNG -> "png";
|
||||||
case IMAGE_SVG -> "svg";
|
case IMAGE_SVG -> "svg";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user