Java 핸드폰에서 찍은 이미지 업로드시 주의사항

2025. 1. 6. 21:27Java

핸드폰에서 찍은 이미지를 서버에 업로드시 width, height 정보를 가져올때, EXIF orientation를 고려해야 함

그냥 width, height 정보를 가져오면, 옆으로 돌려서 찍은 사진의 경우 width와 height가 바껴서 나옴

pom.xml

<dependencies>
    <dependency>
        <groupId>com.drewnoakes</groupId>
        <artifactId>metadata-extractor</artifactId>
        <version>2.18.0</version> <!-- Latest version -->
    </dependency>
</dependencies>

Java

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifIFD0Directory;

import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ExifProcessor {

    public static void main(String[] args) {
        // Input and output image paths
        String inputPath = "C:/uploads/original_image.jpg"; // Replace with your image path
        String outputPath = "C:/uploads/processed_image.jpg";

        try {
            // Read image and EXIF metadata
            File inputFile = new File(inputPath);
            Metadata metadata = ImageMetadataReader.readMetadata(inputFile);

            // Display all metadata tags
            System.out.println("Metadata:");
            for (Directory directory : metadata.getDirectories()) {
                for (Tag tag : directory.getTags()) {
                    System.out.println(tag);
                }
            }

            // Read EXIF Orientation Tag
            int orientation = 1; // Default orientation (no rotation)
            ExifIFD0Directory exifDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
            if (exifDir != null && exifDir.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
                orientation = exifDir.getInt(ExifIFD0Directory.TAG_ORIENTATION);
            }

            // Rotate image based on orientation
            BufferedImage originalImage = ImageIO.read(inputFile);
            BufferedImage rotatedImage = rotateImage(originalImage, orientation);

            // Save processed image
            ImageIO.write(rotatedImage, "jpg", new File(outputPath));

            System.out.println("Image processed and saved: " + outputPath);

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Failed to process image.");
        }
    }

    // Rotate image based on EXIF orientation
    private static BufferedImage rotateImage(BufferedImage image, int orientation) {
        int width = image.getWidth();
        int height = image.getHeight();

        // Handle different EXIF orientations
        switch (orientation) {
            case 6: // 90° CW
                return transformImage(image, width, height, Math.PI / 2);
            case 3: // 180°
                return transformImage(image, width, height, Math.PI);
            case 8: // 270° CW
                return transformImage(image, width, height, -Math.PI / 2);
            default: // No rotation
                return image;
        }
    }

    // Perform the rotation transformation
    private static BufferedImage transformImage(BufferedImage image, int width, int height, double angle) {
        // Create an affine transform for rotation
        AffineTransform transform = new AffineTransform();
        transform.translate(width / 2.0, height / 2.0);
        transform.rotate(angle);
        transform.translate(-height / 2.0, -width / 2.0);

        // Perform the transformation
        AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
        BufferedImage rotatedImage = new BufferedImage(height, width, image.getType());
        Graphics2D g2d = rotatedImage.createGraphics();
        g2d.drawImage(image, op, 0, 0);
        g2d.dispose();

        return rotatedImage;
    }
}