gradle
implementation 'com.drewnoakes:metadata-extractor:2.18.0'
maven
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.18.0</version>
</dependency>
- 원본 이미지 파일을 InputSteam 클래스로 변환 후 metadata 추출
- 추출한 meta데이터에서 방향 값(orientation) 추출
- 원본의 orientation 값에 따라 방향을 설정해줌
- 이미지 resize 후 S3에 업로드
private MultipartFile resizeImageFile(String fileName, String fileExt, MultipartFile file, int targetWidth) {
try {
// file에서 메타데이터 추출
Metadata metadata = getMetadata(file.getInputStream());
// 메타데이터에서 방향값 추출
int orientation = getOrientation(metadata);
// MultipartFile -> BufferedImage Convert
BufferedImage image = ImageIO.read(file.getInputStream());
// 이미지 파일 방향이 1이 아닌 경우 파일 회전
if (orientation != 1) {
image = rotateImage(image, orientation);
}
// newWidth : newHeight = originWidth : originHeight
int originWidth = image.getWidth();
// origin 이미지가 resizing될 사이즈보다 작을 경우 resizing 작업 안 함
if (originWidth < targetWidth)
return file;
BufferedImage bufferedImage = Scalr.resize(image, targetWidth);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, fileExt, baos);
baos.flush();
return new MockMultipartFile(fileName, file.getOriginalFilename(),
file.getContentType(), baos.toByteArray());
} catch (IOException e) {
throw new AmazonS3Exception("Cannot resize image file");
} catch (MetadataException e) {
throw new RuntimeException(e);
}
}
resizeImageFile(이미지 리사이즈 전체 코드)
public Metadata getMetadata(InputStream inputStream) {
Metadata metadata;
try {
metadata = ImageMetadataReader.readMetadata(inputStream);
} catch (ImageProcessingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
return metadata;
}
getMetadata(메타데이터 가져오기)
metadata 추출하는 방법은 file, inputStream을 이용하는 방법 2가지가 있음 여기서는 inpustStream을 이용함(관련 문서)
public Integer getOrientation(Metadata metadata) throws MetadataException {
int orientation = 1;
Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
// directory는 있는데 그 안에 orientation값이 없을 수 있어 두개 다 체크
if(directory != null && directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
}
return orientation;
}
getOrientation(방향값 가져오기)
public BufferedImage rotateImage (BufferedImage bufferedImage, int orientation) {
BufferedImage rotatedImage;
if(orientation == 6 ) {
rotatedImage = Scalr.rotate(bufferedImage, Scalr.Rotation.CW_90);
} else if (orientation == 3) {
rotatedImage = Scalr.rotate(bufferedImage, Scalr.Rotation.CW_180);
} else if(orientation == 8) {
rotatedImage = Scalr.rotate(bufferedImage, Scalr.Rotation.CW_270);
} else {
rotatedImage = bufferedImage;
}
return rotatedImage;
}
rotateImage(방향값을 기준으로 이미지를 돌려줌)
참고 사이트