일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- vue 이벤트 수신
- 이벤트 수식어
- 프로그래머스 프론트엔드 데브코스
- 리스트 렌더링
- Spacer
- SCSS import
- SCSS forward
- SCSS use
- react next
- vue 지역 컴포넌트
- 프로그래머스 K_Digital Training
- KDT 프로그래머스
- 프로그래머스 데브코스
- 고양이 사진 검색기
- KDT 프로그래머스 데브코스 프론트엔드
- 폼 입력 바인딩
- 리액트
- 다른컴퓨터에서 git사용
- vuex map
- git 같은계정 다른 컴퓨터
- 쌓임맥락
- netlify redirect
- 프로그래머스 데브코스 프론트엔드
- intersection opserver
- vue mixin
- Vue
- SCSS extend
- flex
- postcss
- nextjs사용법
- Today
- Total
혼자 적어보는 노트
모바일 이미지 업로드 시 이미지 회전 현상 본문
모바일 이미지 업로드 시 이미지 회전 현상
프로젝트를 리팩토링하고 확인하는 과정에서
핸드폰으로 촬영한 이미지를 업로드할 때 회전되어서 보여지는 현상이 발생했다.
사용하는 핸드폰은 아이폰이고 원본(실제크기) 그대로 올릴 경우 제대로 나타나지만
업로드 할 때 아이폰 기능에서 파일 사이즈를 줄일 경우 회전이된다.
왜 사진이 회전될까?
휴대폰을 세워서 정상적인 각도에서 사진을 찍으면 정상적으로 나타나지만
핸드폰의 각도를 기울여서 찍은 경우 틀어져서 저장이 되고 이 회전 정보를 기억한다고 한다.
이 회전된 정보는 EXIF라는 메타정보의 orientation 에 저장이 되는데
핸드폰의 경우 이 정보를 읽어서 정상적으로 갤러리에 보여주지만
브라우저는 이 orientation정보를 읽지 못한다고 한다,,
해결을 위해 시도한 방법
blueimp-load-image 라이브러리 사용
File, Blob 객체로 제공되는 이미지를 img 또는 canvas요소로 변환해주는 라이브러리이다.
옵션이되는 기능에 메타데이터를 분석하고 Exif의 방향값을 덮어쓰고 크기 조정 후에
이미지 헤더를 복원하는 방법을 제공한다고 한다.
[promise방식]
loadImage(fileBlob, { meta: true, orientation: true, canvas: true }).then(
async (data) => {
data.image.toBlob((blob) => {
const rotateFile = new File([blob], fileBlob.name, { type: fileBlob.type });
const reader = new FileReader();
reader.readAsDataURL(rotateFile);
reader.onload = () => {
setImageSrc(reader.result);
onChange(reader.result);
};
});
},
);
찾아보니 위와 같이 promise 형식으로 orientation을 변경시키고 변경된 data를 받아서
처리하는 코드를 작성할 수 있었다.
=> 그런데 안된다..??
[콜백 방식]
loadImage(fileBlob, { meta: true, orientation: true, canvas: true }).then(
(data) => {
if (data.imageHead && data.exif) {
// data.imageHead가 있는 것만 변경.
loadImage.writeExifData(data.imageHead, data, 'Orientation', 6);
alert(data.exif + ' imageHead');
data.image.toBlob(async function (blob) {
loadImage.replaceHead(blob, data.imageHead, async function (newBlob) {
newBlob.name = fileBlob.name;
alert(newBlob);
const reader = new FileReader();
reader.readAsDataURL(newBlob);
reader.onload = () => {
setImageSrc(reader.result);
onChange(reader.result);
};
});
}, 'image/jpeg');
} else {
// const reader = new FileReader();
// reader.readAsDataURL(fileBlob);
// reader.onload = () => {
// setImageSrc(reader.result);
// onChange(reader.result);
// };
}
},
);
위와 같이 콜백방식으로도 작성해보았다. 일단 되는지부터 확인하기위해 코드를 조금 막 작성했다.
(위 방법 말고도 내 코드에 문제가 있나 해서 여러 코드를 작성했었음...)
그런데!!
다른사람들이 된다는 코드를 사용했음에도 불구하고 업로드 시 회전된 이미지로 보였다.
exif-js 라이브러리 사용
orientation값을 직접 확인하기위해 exif-js 라이브러리를 설치해서
이미지 업로드 시 값을 띄워보기로 했다.
EXIF.getData(fileBlob, () => {
const orientation = EXIF.getTag(fileBlob, 'Orientation');
alert(orientation + ' data');
});
그런데 갤러리에서 원본 이미지로 올렸을 때는 값이 6이 나타났다. (값이 6이면 왼쪽으로 90도 회전되어야 한다)
근데 값과는 달리 원본 이미지의 경우는 업로드 시 정방향으로 제대로 보이는 상태이다.😱
그리고 업로드 시 이미지 사이즈를 조절하여 등록할 경우 orientation값은 1이 나왔다.
???? orientation값이 1인데 왜 회전이 되어서 보이는걸까??
추측..
원본 이미지의 orientation는 업로드할 때 알아서 1로 변경되어 업로드 되게끔 처리가 되는데
아이폰 내부의 파일 크기 변환 과정에있어서 기존의 orientation (6)인 상태로 압축이 되어버려서
회전된 이미지가 정방향 이미지인 것 처럼 데이터가 덮어 씌워져버린 것이 아닐까 추측해봤다.
결국 회전된 상태 자체가 1(정방향)으로 인식을 해버리니까
orientation값을 아무리 1로 다시 변경해도 당연히!!! 변경이 안되는 것이다!!
그러면 다른 방법을 사용할 순 없을까 하는 생각으로
키워드를 변경해서 검색을 해본 결과
나와 같은 문제를 겪는 사람이 있었고 이전에도 제기된 문제였다고 하는데
추측으로는 IOS의 버그라고 한다.
다른 사이트나 앱을 살펴보니 보통 내 사례처럼 회전이 되는채로 두거나
이미지 크기 조정하는 창으로 넘어가지 않고 바로 원본이미지를 편집할 수 있는
에디터로 넘어가는 형태로 구현되어 있었다.
꽤 시간을 썼지만 일단 이미지를 자동으로 맞춰주는 방법은 미루고
차라리 사용자가 이미지를 직접 회전할 수 있게 방식을 바꾸기로 했다.
해결하지 못하고 끝난 사례지만 혹시나 해결하는 방법을 알게 되면 포스팅을 수정할 예정이다.
'Error' 카테고리의 다른 글
[Webpack] webpack-dev-server script 2번 실행 (0) | 2022.09.01 |
---|---|
Component definition is missing display name (0) | 2022.07.29 |
unable to resolve dependency tree (0) | 2022.05.27 |
error: failed to push some refs to 'github repository 주소' (0) | 2022.04.21 |
Manifest: Line: 1, column: 1, Syntax error (0) | 2022.03.10 |