iOS 이미지 용량 문제

요리하는코더·2021년 10월 18일
4

React-Native

목록 보기
2/2
post-thumbnail
post-custom-banner

Trouble shooting 관련한 글은 잘 작성하지 않았는데 이번에 알게 된 정보를 정리하면 좋을 거 같아서 정리해 보려고 한다.

TL;DR

  • nginx.conf 파일에 사이즈를 늘려보자.
  • ExpoImagePicker.launchImageLibraryAsync를 사용한다면 ios에서 quality 값에 0.2를 주자.
  • 아이폰은 HEIC 포맷을 사용해서 JPEG로 변경 시 용량이 증가한다.

문제 상황

회사에서 이미지 업로드 구현을 하는데 용량 문제가 계속 발생하였다.
에러 메세지를 살펴보니 413 Request Entity Too Large가 발생하는 것이었다.
바로 구글신에게 검색을 진행하였다.
Nginx 413 Request Entity Too Large 에러 해결하기, 파일 업로드 사이즈라는 글이 있어서 바로 참고를 하니 nginx를 거쳐서 파일 업로드를 할 때 용량 제한이 있는 것이었다.
기본 사이즈는 1Mbyte인데 5Mbyte까지 허용하려고 했으니 에러가 나는 게 당연했다.

따라서 nginx.conf 파일의 용량을 늘려서 해결했다!!👏👏👏

이러면 단순하게 해결했겠지만 의문이 들었다.

도대체 이미지 사이즈가 얼마길래 파일이 안 올라갈까??🤔

그리고 5Mbyte로 올려도 안 올라가는 이미지들이 있었다.

사진첩에서 이미지의 용량을 살펴보니 ??? 5Mbytes는 무슨 2.4Mbytes였다...😱

그래서 임시로 사이즈를 올리고 서버에서 확인해보니 대략 8Mbytes 정도였고 다른 이미지들도 작으면 1.5에서 크면 2배 정도 사이즈가 커졌다...?

이미지 올릴 때 잘못된 게 있나 싶어서 일단 코드를 계속 비교했는데 다른 게 없었다.

결국 아는 형들과 오픈 채팅 방에 질문을 올렸는데 처음에는 확실한 답을 얻을 수 없었다.
그러다가 아는 형 중 한명이 예전에 ios 앱 개발을 해본적이 있어서 코드를 같이 살펴봐주었다.

아이폰에서는 이미지를 저장할 때 이미지 포맷을 전용 포맷으로 저장한다는 것을 알려주었다.
그리고 코드를 보면서 어디가 에러인 거 같은지 알려주었다.

이를 토대로 문제를 해결한 방법을 정리하려고 한다.

해결 방법

  1. ImagePicker 문서 살펴보기

먼저 이미지 가져오는 코드를 살펴보니 ImagePicker.launchImageLibraryAsync를 사용하는 것을 알 수 있었다. 그 중 quality 값이 있길래 먼가 이것과 관련있을 거 같았다.

Note: If the selected image has been compressed before, the size of the output file may be bigger than the size of the original image.
좀 더 살펴보니 위와 같은 말이 있었다.
그리고 위에서 아는 형이 알려줬던 아이폰은 다른 이미지 포맷으로 저장한다는 것이 기억났다.

일단 테스트를 위해 quality 값을 줄여보니 사이즈가 줄어드는 것을 확인했다.

그리고 위 문서 하단에 있는 View source code for ImagePicker를 눌러서 코드를 살펴보았다.

expo/packages/expo-image-picker/ios/EXImagePicker/EXImagePicker.m의 코드를 살펴보니 const CGFloat EXDefaultImageQuality = 0.2;라는 코드가 존재했다.

추가로 NSData *data = UIImageJPEGRepresentation(image, quality == nil ? EXDefaultImageQuality : [quality floatValue]); 라는 코드가 사용되는 거 같은데 EX에만 적용이 된 거 같고 0.2를 적용한 거 같아서 quality에 0.2를 주니 사이즈가 폰에 저장되는 것과 같았다.

아마 아이폰의 경우 quality의 Default 값을 0.2로 해줘야하는데 실제 코드에는 적용이 안 된 거 같다.

문제점을 알았으니 Platform.OS를 사용해 ios인 경우를 분기처리해서 해결했다!

이렇게 해결을 하고 끝낼 수도 있지만 위의 방법을 바로 안 것은 아니고 아래의 과정들이 있었으므로 좀 더 문제 해결 방법에 대해 서술해보려고 한다.

  1. 이슈 찾아보기

아래의 이슈들은 react-native-image-picker와 관련된 이슈인데 내용이 비슷해서 살펴보니 expo에서의 이슈와 비슷한 거 같았다.

confuse about image image local size and upload size #1272

먼저 로컬 사이즈와 업로드 된 사이즈가 다르다는 이슈가 존재했다.
위의 이슈에서는 크게 해결책이 제시되어 있지 않았지만 Images posted to server via fetch get their size inflated significantly #27099 라는 이슈가 연결되어 있었다.

이제 다음 이슈를 살펴보았다.
rn-fetch-blob을 사용해서 해결한 사람, base64로 변경해서 해결한 사람, 새로운 버젼에서는 해결되었다는 이야기 등 많은 내용이 있었다.
영어로 나와있어도 우리에게는 구글 번역이 있으니 겁먹지 말고 천천히 살펴보자!

여러 댓글 중 MrZhaoCn이라는 분이 제일 근본적으로 설명을 해준 거 같아서 내용을 작성해보려고 한다.

React Native에서 jpg image를 가져올 때 RCTImageLoader를 하며 다음과 같은 코드로 작성되어 있다.

 NSString *mimeType = nil;
  NSData *imageData = nil;
  if (RCTImageHasAlpha(image.CGImage)) {
      mimeType = @"image/png";
      imageData = UIImagePNGRepresentation(image);
  } else {
      mimeType = @"image/jpeg";
      imageData = UIImageJPEGRepresentation(image, 1.0);
  }
  NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL
                                                      MIMEType:mimeType
                                         expectedContentLength:imageData.length
                                              textEncodingName:nil];

  [delegate URLRequest:requestToken didReceiveResponse:response];
  [delegate URLRequest:requestToken didReceiveData:imageData];
  [delegate URLRequest:requestToken didCompleteWithError:nil];

아까 expo에서 봤듯이 UIImageJPEGRepresentation가 사용됨을 알 수 있다.
UIImageJPEGRepresentation 문서에서 보면 JPEG 이미지를 생성해주는 함수인 것을 알 수 있다.
좀 더 내부적인 코드나 사용법을 살펴보고 싶은데 찾지 못했다 ㅠㅠ

결국 아이폰에서 저장되는 포맷의 파일의 이미지를 JPEG로 만들면서 용량이 커졌다는 것을 알 수 있었다!


추가 공부

추가로 아이폰에서 어떤 형식으로 저장되는지에 대해 검색을 진행했다.

아이폰 HEIC 파일을 JPG로 변환하는 방법 그리고 HEIC 파일을 쓰면안되는 이유라는 좋을 글이 많이 참고가 됐다.

iOS11이 되면서 사진 파일 확장자가 HEIC 포맷으로 저장이 되는 것이었다.
HEIF라고도 하고 HEIC라고도 적었는데 HEIF는 High Efficiency Image Format이고 HEIC는 High Efficiency Image Container이다. 둘다 사용할 수 있는 단어인 거 같다.

특징은 다음과 같다.

  • 복수의 이미지 저장 가능 -> 아이폰을 쓰면 사진들이 영상처럼 나오는 게 있는데 아마 그걸 의미하는 게 아닐까 싶다.
  • 용량 -> JPEG와 비교했을 때 같은 화질에서 용량이 절반이다.
  • HEIF는 최대 12bit까지 정보를 담을 수 있다.
  • 동영상 스틸을 추출하여 저장하는 컨테이너이므로 컬러 매니지먼트도 동영상 방식을 따른다고 한다.
  • 아직 대중화는 많이 안된 거 같다.

아이폰에서 설정 -> 카메라 -> 포멧에서 설정할 수 있다.

거의 비슷한 위치에서 촬영한 이미지 파일들 정보들은 다음과 같았다.
(이미지가 너무 크다...)
1. HEIF 파일

2. JPEG 파일

용량이 2.9MB와 4MB인 것을 알 수 있다.

만약 아이폰에서 찍은 사진이 어디선가 안 보인다면 JPEG로 바꾸는 작업을 통해 해결할 수 있을 거 같다.

느낀 점

이번 문제를 해결하기위해 여러 곳에 질문도 했고 많은 이슈도 찾아보게 되었다.
최대한 조사한 정보를 제공하기 위해서 노력을 했는데 누군가 이런 문제를 직면했을 때 도움이 되면 좋겠다.

좀 더 수정하면 좋을 거 같은 것은 Platform.OS에서 ios인 경우 quality 값을 0.2를 줬는데 HEIF 포맷이 아닌 경우에도 적용이 될 수도 있어서 좀 고려해봐야겠다. 물론 해상도가 크게 나쁘지지는 않아서 큰 문제는 없지만 테스트를 좀 더 해봐야겠다.


참고 자료

profile
요리 좋아하는 코린이
post-custom-banner

0개의 댓글