이미지 업로드 프로세스
1. 컴퓨터가 이미지를 표현하는 법
컴퓨터는 무수히 많은 0과 1(2진수)로 이루어져 있다. 초창기의 컴퓨터는 여러개의 스위치를 활용해 꺼짐과 켜짐의 조합으로 각 숫자, 데이터를 표현하는 방식으로 연산을 진행했고, 그 방식이 여전히 유지되고 있기 때문이죠.
이때, 0과 1을 표현할 수 있는 스위치가 총 10개 존재한다면, 이를 통해 표현할 수 있는 경우의 수는 2의 10승, 1024가 되죠.
컴퓨터 상에서 표현되는 0과 1의 조합 만으로는 1000이라는 숫자가 딱 떨어지게 표현될 수 없다. 이러한 이유로 우리는 딱 떨어지는 숫자 1000이 아닌 1024로 데이터를 표현하게 된겁니다. 결국, 텍스트, 이미지 등 모든 데이터는 컴퓨터 상에서 0과 1의 숫자로 변환되어 표현된다.
1.1 이미지를 확대해보면,
컴퓨터에 이미지를 정말 크게 확대해보면, 작은 네모들로 구성되어 있다.
이를 pixel(픽셀, or 화소)이라고 한다.
- 픽셀이 많을 수록 이미지는 고화질이 된다.
- 픽셀은 0~255까지의 숫자로 저장된다.
- 컬러 이미지를 표현하려면, 빨강, 녹색, 파랑의 조합으로 표현된다.
- 각 색깔은 0~255 사의 값으로 각각 빨강의 정도, 녹색의 정도, 파랑의 정도를 나타냄
- 이미지의 픽셀 위치마다 색깔의 정보가 담긴 6자리 코드가 있고,
- 그 코드를 그림에 맞게 모아놓은 것이 ‘이미지’이다.
2. 프론트엔드에서 이미지
Naver 홈페이지에 들어가서, 개발자 도구를 켜서 이미지가 있는 곳을 확인해보면, 네이버 주소와 관련없는 새로운 주소가 있는 것을 볼 수 있다.
브라우저는 다음과 같은 순서로 파일들을 다운받습니다.
- HTML을 먼저 다운
- CSS, JS를 다운
- HTML의 Img 태그에 src에 사진이 저장된 컴퓨터에 접근해서 다운
2.1 DB에 이미지를 저장하려면?
DB에 이미지를 저장하려면, BLOB(Binary Large Object) 타입을 사용합니다.
즉, 0101의 큰 이진코드를 말합니다.
e.g. 사진을 확대해보면 작은 네모들이 모여서 구성되고, 이 작은 네모의 색깔들은 RGB로 표현가능합니다. 다시 이 RGB 값을 2진코드로 변환해서 저장하는 원리입니다.
그래서 결국에는 엄청 큰 2진코드를 저장하면 됩니다. 그래서 글보다 사진의 용량이 큰 겁니다. 그러면 영상은 수 많은 이미지들을 빠르게 연속적으로 보여주는 것이니까 용량이 훨씬 더 크겠죠? 그림, 오디오, 동영상 등 기타 멀티미디어 오브젝트가 이런식으로 저장됩니다.
하지만, 이렇게 DB에 저장하게 되면, DB를 관리하기가 너무 힘들어집니다. DB 용량도 굉장히 커집니다. 그래서 사진만 저장하는 컴퓨터를 따로 만듭니다. 거기다 사진을 저장하고, 그 사진을 URL로 갖고 옵니다.
따로 엄청 용량이 큰 컴퓨터를 구매하고, 네트워크 설정하기는 귀찮고 번거롭기 때문에,
AWS(amazon), GCP(google), AZURE(microsoft)와 같은 클라우드 서비스를 이용합니다.
즉, 이들은 storage를 빌려주는 = 컴퓨터를 빌려주는 서비스입니다.
💡 storage
이미지 프로세스를 이해하기 위해서는
storage사용을 알아야 합니다.storage또한 컴퓨터이며, 여러 컴퓨터들을 연결시켜 놓은 큰 용량을 담을 수 있는데이터베이스입니다.
2.2 이미지 검증
이미지를 업로드할때 필요이상으로 큰사이즈의 이미지나, 초고화질 이미지를 보내게 되면, 저장공간을 많이 차지하기 때문에 비용 측면에 있어서 부담이 될 수 있다. 또한 이미지를 업로드하는데 html파일이나 한글파일을 잘못 업로드 하는 경우도 있다.
따라서 위와 같은 일들을 방지하기 위해 이미지를 업로드 할 때 이미지의 크기를 지정하고, 확장자를 검증하는 등 이미지 검증 단계를 거쳐 업로드 하는 것이 좋다.
💡 jpeg와 jpg
옛날에는 확장자를 3글자 밖에 못써서, jpeg를 잘라서 jpg로 썻었습니다. 현재는 이 3글자 제한이 없어져서 jpeg를 쓸 수 있게 되었습니다. 결론은 jpeg나 jpg나 같은 것입니다.
3. 백엔드에서 이미지
cf. 이미지 업로드 과정은 회사 또는 보완,성능의 중요도에 따라 전체적인 구조는 완전히 다를 수 있음
3.1 기본적인 이미지 업로드 프로세스
- 브라우저에서 사용자가 업로드할 이미지 파일을 선택
- 브라우저에서 선택된 파일을 변수에 저장
- 변수에 담긴 내용을
파일 객체라고 하며, 파일 사이즈 등 파일에 대한 정보를 담고 있음
- 변수에 담긴 내용을
- 이제 브라우저에서는 파일 객체를 백엔드 서버에 업로드 요청한다
- 이를 위해 백엔드 서버에서는 파일 업로드를 하는 API를 제작해야 함
- 백엔드 서버에서는 API를 통해 받은 파일을 DB에 저장 시 BLOB타입으로 저장함.
- 하지만 파일은 큰 용량을 차지하기 때문에, 모든 파일을 DB에 저장하는 것은 비효율적
그렇다면 이미지 파일은 어디에 저장해야할까요? 바로 Storage service를 이용한다. e.g. Storage service를 제공하는 대표적인 회사는 AWS, GCP, Azure
3.2 이미지 파일이 storage에 저장되는 프로세스
- 브라우저에서 파일 첨부 후 파일 업로드 API를 요청하면 Storage에 파일을 저장
- Storage에서는 파일을 저장한 결과로 사진을 다운로드 할 수 있는 주소를 반환
- 백엔드에서는 반환된 주소를 브라우저로 보내준다.
위의 과정을 1차라고하면, 2차 과정으로는 게시글의 내용과 함께 파일URL주소를 DB에 저장하는 과정이 필요하다.
- 브라우저에서 게시글을 작성하면,
- title, content, 업로드한 파일의 URL를 포함해서 게시물 등록 API를 요청
- 요청된 API를 통해 DB에 저장이 되며 테이블 구조에 따라
- 게시글 테이블에 함께 저장되거나, 이미지는 이미지테이블에 따로 저장되는 구조를 가짐.
💡 화면에 이미지가 보여지는 프로세스
- 브라우저에 주소를 입력하고 접속하면 프론트 서버에서는 html, css, js를 보내줍니다.
- 브라우저에서는 html를 코드를 실행시켜 화면에 그려준다.
- 이때 이미지 주소를 담고있는 img태그는 단순 문자열로 되어있으며,
- 실제로 실행되는 것은 브라우저에 화면이 그려지고 나서 이미지 주소에 2차적으로 재요청한다.
- 재요청을 통해 사진 저장소(storage 등)에서 사진을 다운받은 후 화면에 나타나기 때문에,
- 사진이 화면에 보여지는 과정은 다른 요소들보다 시간이 소요된다는 것을 이해해야 한다.
4. 이미지 업로드 성능
4.1 LazyLoad vs PreLoad
LazyLoad- 페이지를 읽어주는 시점에 중요하지 않은 리소스 로딩을 추후에 하는 기술
- e.g. 스크롤이 내려가면서 이미지가 필요한 때가 되면 로드
- e.g. 이미지가 10장이 넘는 페이지가 있다고 가정할 때 이미지를 모두 다 로드가 될 때까지 기다리면,
- 페이지의 로딩을 길어지게 될 것입니다.
- 하지만, 맨 위의 화면에 보이는 이미지만 로드를 한 후에,
- 스크롤을 내리면서 이미지가 보여져야 할 때마다 이미지를 로드한다면, 데이터의 낭비를 막을 수 있습니다!
PreLoad- 페이지를 읽어줄 때 미리 리소스를 받아놓는 기술
- e.g. 이미지가 10장이 넘는 페이지가 있다고 가정
LazyLoad의 경우에는 필요할 때마다 데이터를 로드하는 방법이라면,PreLoad의 경우에는 모든 데이터들을 미리 로드해놓고 대기하는 방식