업무용/springjava
바이너리 이미지 정방향으로 자바에서 돌리기
SEOKIHOUSE
2024. 7. 16. 15:04
요 녀석을.. 돌려버리자 갓 클소
package tests;
import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageInputStream;
import org.w3c.dom.NodeList;
import humetro.pm.haBscMttrMng.service.vo.HaBscMttrVo;
public class test {
// 사용 예시
public static void main(String[] args) {
HaBscMttrVo vo = new HaBscMttrVo();
try {
// 이미지 파일을 바이트 배열로 읽어오는 코드가 필요합니다.
byte[] imageData = vo.getPhotoBt();// 이미지 바이트 배열을 여기에 넣으세요
byte[] correctedImageData = correctOrientation(imageData);
// 수정된 이미지를 저장하거나 사용하는 코드를 여기에 추가하세요
// 예: ImageIO.write(correctedImage, "jpg", new File("corrected_image.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] correctOrientation(byte[] imageData) throws IOException {
ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
ImageInputStream iis = ImageIO.createImageInputStream(bis);
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
if (!readers.hasNext()) {
return imageData; // 원본 이미지 데이터 반환
}
ImageReader reader = readers.next();
String formatName = reader.getFormatName().toLowerCase();
if (formatName.equals("jpeg") || formatName.equals("jpg") || formatName.equals("jpe") || formatName.equals("jfif")) {
formatName = "jpg";
}
reader.setInput(iis, true);
BufferedImage image = reader.read(0);
IIOMetadata metadata = null;
try {
metadata = reader.getImageMetadata(0);
} catch (IOException e) {
//System.out.println("Failed to read metadata: " + e.getMessage());
// 메타데이터를 읽을 수 없는 경우, 기본값 방향 출력
metadata = null;
}
int orientation = (metadata != null) ? getExifOrientation(metadata) : 1;
BufferedImage correctedImage;
switch (orientation) {
case 1: // 정상
correctedImage = image;
break;
case 2: // 좌우 반전
correctedImage = flip(image, false, true);
break;
case 3: // 180도 회전
correctedImage = rotate(image, 180);
break;
case 4: // 상하 반전
correctedImage = flip(image, true, false);
break;
case 5: // 90도 회전 후 좌우 반전
BufferedImage rotated = rotate(image, 90);
correctedImage = flip(rotated, false, true);
break;
case 6: // 90도 시계 방향 회전
correctedImage = rotate(image, 90);
break;
case 7: // 270도 회전 후 좌우 반전
rotated = rotate(image, 270);
correctedImage = flip(rotated, false, true);
break;
case 8: // 270도 시계 방향 회전
correctedImage = rotate(image, 270);
break;
default:
correctedImage = image;
}
// BufferedImage를 byte 배열로 변환
return bufferedImageToByteArray(correctedImage, formatName);
}
private static byte[] bufferedImageToByteArray(BufferedImage image, String formatName) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
// 이미지 형식이 지원되는지 확인
if (!ImageIO.getImageWritersByFormatName(formatName).hasNext()) {
throw new IllegalArgumentException("Unsupported image format: " + formatName);
}
// 알파 채널 처리
BufferedImage convertedImg = image;
if (image.getColorModel().hasAlpha()) {
convertedImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
convertedImg.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
}
// 이미지 쓰기
ImageIO.write(convertedImg, formatName, baos);
} catch (IOException e) {
throw new IOException("Error writing image: " + e.getMessage());
}
return baos.toByteArray();
}
private static int getExifOrientation(IIOMetadata metadata) {
int orientation = 1;
String[] metadataFormats = metadata.getMetadataFormatNames();
for (String format : metadataFormats) {
IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(format);
NodeList nodes = root.getElementsByTagName("app1");
if (nodes.getLength() > 0) {
for (int i = 0; i < nodes.getLength(); i++) {
IIOMetadataNode node = (IIOMetadataNode) nodes.item(i);
if (node != null) {
try {
byte[] exif = (byte[]) node.getUserObject();
if (exif != null && exif.length > 20) {
// EXIF 헤더 확인
if (exif[0] == 'E' && exif[1] == 'x' && exif[2] == 'i' && exif[3] == 'f') {
// EXIF 데이터에서 방향 정보 찾기
for (int j = 0; j < exif.length - 1; j++) {
if (exif[j] == 0x12 && exif[j+1] == 0x01) {
orientation = exif[j + 8] & 0xFF;
return orientation;
}
}
}
}
} catch (ClassCastException e) {
} catch (ArrayIndexOutOfBoundsException e) {
} catch (NullPointerException e) {
}
}
}
}
}
return orientation;
}
private static BufferedImage rotate(BufferedImage image, int degrees) {
double radians = Math.toRadians(degrees);
int srcWidth = image.getWidth();
int srcHeight = image.getHeight();
int newWidth = srcWidth;
int newHeight = srcHeight;
if (degrees == 90 || degrees == 270) {
newWidth = srcHeight;
newHeight = srcWidth;
}
BufferedImage rotated = new BufferedImage(newWidth, newHeight, image.getType());
AffineTransform at = AffineTransform.getRotateInstance(radians, newWidth / 2.0, newHeight / 2.0);
if (degrees == 90) {
at.translate((newWidth - srcWidth) / 2.0, (newHeight - srcHeight) / 2.0);
} else if (degrees == 270) {
at.translate(-(newWidth - srcWidth) / 2.0, -(newHeight - srcHeight) / 2.0);
}
AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
op.filter(image, rotated);
return rotated;
}
private static BufferedImage flip(BufferedImage image, boolean horizontal, boolean vertical) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage flipped = new BufferedImage(width, height, image.getType());
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int newX = horizontal ? width - 1 - x : x;
int newY = vertical ? height - 1 - y : y;
flipped.setRGB(newX, newY, image.getRGB(x, y));
}
}
return flipped;
}
}