[이미지] 모바일에서 사진 찍어 이미지 등록 시 회전 막기
이번 포스팅에서는 모바일에서 input[type=file]을 사용하여 서버로 이미지 등록 시 회전되는걸 막으려고 한다.
필자는 실제로 회사 프로젝트 때 활용하여 사용하였다.
스마트폰 기종에 따라 사진을 찍으면 이미지가 자동으로 회전되서 업로드가 된다.
먼저 본질적으로 막는 방법은 없는 것 같다.
그래서 이미지를 등록 시 자바스크립트 플러그인을 통하여 orientation 값에 따라 서버에서 강제로 이미지를 회전 시켜 저장하려한다.
먼저 자바스크립트를 통하여 orientation 값을 구하려고 한다.
플러그인을 다운받자.
플러그인을 사용하여 html 코드로 테스트 해보려고 한다.
데스크탑에서 테스트하면 orientation 값이 항상 1일 것이다.
모바일에서 테스트 하려면
1. 닷홈 무료 호스팅
2. 서버에 jsp 배포
편한걸로 하자.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="js/load_image/load-image.js"></script>
<script src="js/load_image/load-image-scale.js"></script>
<script src="js/load_image/load-image-meta.js"></script>
<script src="js/load_image/load-image-fetch.js"></script>
<script src="js/load_image/load-image-orientation.js"></script>
<script src="js/load_image/load-image-exif.js"></script>
<script src="js/load_image/load-image-exif-map.js"></script>
<script src="js/load_image/load-image-iptc.js"></script>
<script src="js/load_image/load-image-iptc-map.js"></script>
<script src="js/load_image/vendor/jquery.Jcrop.js"></script>
</head>
<body>
<input type="file" id="img">
<script>
$('#img').on('change', dropChangeHandler);
function dropChangeHandler(e) {
e.preventDefault()
e = e.originalEvent
var files = e.target.files;
var filesArr = Array.prototype.slice.call(files);
filesArr.forEach(function(f, index) {
fileName = $("#img").val();
fileName = fileName.slice(fileName.indexOf(".") + 1).toLowerCase();
if (fileName != "jpg" && fileName != "png" && fileName != "gif" && fileName != "bmp" && fileName != "apng" && fileName != "avif" && fileName != "bpg" && fileName != "dds" && fileName != "dng" && fileName != "exr" && fileName != "jpeg" && fileName != "heif" && fileName != "psd" && fileName != "raw" && fileName != "rgbe" && fileName != "tiff" && fileName != "webp") {
alert('이미지 파일만 업로드 가능합니다.');
$("#img").val("");
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var file = f;
var options = {
maxWidth: 500,
canvas: true,
pixelRatio: window.devicePixelRatio,
downsamplingRatio: 0.5,
orientation: true
}
if (!file) {
return
}
displayImage(file, options)
}
reader.readAsDataURL(f);
});
}
function displayImage(file, options) {
currentFile = file
if (!loadImage(file, updateResults, options)) {
result.children().replaceWith()
}
}
function updateResults(img, data) {
var fileName = currentFile.name
var href = img.src
var dataURLStart
var content
if (!(img.src || img instanceof HTMLCanvasElement)) {
} else {
displayMetaData(data);
}
}
function displayMetaData(data) {
if (!data) return
var exif = data.exif
var iptc = data.iptc
if (exif) {
if (exif.get('Orientation') == null) {
orientation = 1;
} else {
orientation = exif.get('Orientation');
}
} else {
orientation = 1;
}
alert(orientation);
}
</script>
</body>
</html>
서버로 이미지를 업로드 할 때 orientation 값도 같이 업로드 하자.
이미지 회전 하는 소스만 적었다.
일단 먼저 서버에 업로드한 이미지를 저장한다.
자바스크립트 플러그인을 이용해서 추출한 orientation 값에 따라 회전 값을 적었다.
[1, 2] = 정상적인 이미지
[3, 4] = 180도 회전된 이미지
[5, 6] = 270도 회전된 이미지
[7, 8] = 90도 회전된 이미지
그러므로 아래처럼 회전 시켜야한다.
[1, 2] = 아무 처리 필요없음
[3, 4] = 180도 회전 시킴
[5, 6] = 90도 회전 시킴
[7, 8] = 270도 회전 시킴
자바 Graphics2D을 이용하여 rotate를 시키고 이미지를 저장하면 정삭적인 이미지가 저장이 될 것이다.
switch (orientation) {
case 1:
orientation = 0;
break;
case 2:
orientation = 0;
break;
case 3:
orientation = 2;
break;
case 4:
orientation = 2;
break;
case 5:
orientation = 1;
break;
case 6:
orientation = 1;
break;
case 7:
orientation = 3;
break;
case 8:
orientation = 3;
break;
}
if(orientation != 0) {
BufferedImage oldImage = ImageIO.read(new FileInputStream(saveFilePath + newInfImgFileName));
BufferedImage newImage1 = new BufferedImage(oldImage.getHeight(),oldImage.getWidth(), oldImage.getType());
Graphics2D graphics = (Graphics2D) newImage1.getGraphics();
graphics.rotate(Math.toRadians(90 * orientation), newImage1.getWidth() / 2, newImage1.getHeight() / 2);
graphics.translate((newImage1.getWidth() - oldImage.getWidth()) / 2, (newImage1.getHeight() - oldImage.getHeight()) / 2);
graphics.drawImage(oldImage, 0, 0, oldImage.getWidth(), oldImage.getHeight(), null);
ImageIO.write(newImage1, ext, new FileOutputStream(saveFilePath + newInfImgFileName));
}