본문 바로가기
리액트 공부와 함께 하는 일상/4주차

[TIL] 4주차 - 5. 이미지 파일 업로드

by fefe94 2022. 2. 8.

이미지 프로세스 이해 (이미지 서버, 스토리지 포함)

 

이미지 프로세스를 이해하기 위해서는 storage 사용을 알아야 합니다.

storage 또한 컴퓨터이며 여러 컴퓨터들을 연결시켜 놓은 큰 용량을 담을 수 있는 데이터베이스 입니다.

 

이미지 파일 업로드 시

데이터 베이스에는

이미지 파일이 저장된 주솟값이 들어가며

실제 저장되는 위치storage입니다.

 

 

uploadFile 이라는 api가 있을때, 파일을 선택하고 uploadFile을 요청하게 될 경우,

backend에서 storage로 파일을 전송하게 됩니다.

 

우리가 이미지를 보기 위해서는 주소를 사용해 접근하게 됩니다.

즉, storage에서는 backend로 이미지 주소를 넘겨주게 되며

이 주소를 다시 front에게 주게 됩니다.

우리는 이 주소를 가지고 api 요청 시, image에 대한 주소를 보낼 수 있게 되는 것 이며,

이 정보들을 DataBase에 저장하게 됩니다.

 

 


스토리지 저장소

AWS 아마존 웹 서비스

GCP 구글 클라우드 플랫폼

AZURE 마이크로소프트 애저

 

위 세개의 클라우드 컴퓨팅 플랫폼 들은

클라우드 3대장으로 불립니다.

 

클라우드 컴퓨팅 (cloud computing) : 
사용자의 직접적인 활발한 관리 없이 특히, 데이터 스토리지(클라우드 스토리지) 와 컴퓨팅 파워와 같은 컴퓨터 시스템 리소스를 필요 시 바로 제공(on-demand availability)하는 것 을 말한다. 
시스템 리소스, 시스템 자원 :
리소스라는 것은 실제 프로그램의 실행에서는 없어도 되는 메뉴, 비트맵 폰트, 단축키, 문자열 표, 다이얼로그, 바탕화면 아이콘, 커서, 사운드, 통신등을 의미

 

바로 이 클라우드 컴퓨팅 플랫폼에서 컴퓨터를 빌려주는데,

컴퓨터에서 사용할 수 있는 shell을 빌려줍니다.

 

CLI로 폴더 생성, 복사, 삭제 다 할 수 있고

유료로 컴퓨터 메로리를 빌릴 수 있습니다.

 

(가장 인기가 많은 것은 AWS 이고

GCP, AZURE가 치고 올라 오고 있습니다.)

 

여기서 storage도 빌려주며

이곳에 사진 저장을 할 수 있는 것입니다.

 


 

 

위 사진처럼 브라우저 출력시

html, css, js 같이 하드 코딩된 부분들을 먼저 그려주고

다 그리고 나서 이미지, 폰트들이

저장되어 있는 위치로부터 불려와 다운 받아집니다.

 


이미지 검증 (사이즈, 확장자)

이미지 확장자 검증하기

 

이미지 파일input 태그에 넣을 때 확장자를 검증하는 방법은 크게 2가지가 있습니다.

 

첫 번째 방법은 input 태그에 accept속성을 이용하는 것이고,

두 번째 방법은 onChange 함수 안에서 type을 비교하는 것입니다.

 


 

input 태그에 accept 속성 활용하여 확장자 검증하기

<div>
				<img style={{ width: '500px' }} id="image" />
				<input type="file" accept="image/png" onChange={readImage}></input>
</div>

accept를 통해 png 확장자만 가능하게 했습니다.

 

 


 

 

onChange 함수 안에서 type을 이용하여 검증하기

import { gql, useMutation } from "@apollo/client";
import { ChangeEvent, useState } from "react";
import { checkFileValidation } from "../../src/commons/libraries/utils";
import {
  IMutation,
  IMutationUploadFileArgs,
} from "../../src/commons/types/generated/types";

const UPLOAD_FILE = gql`
  mutation uploadFile($file: Upload!) {
    uploadFile(file: $file) {
      url
    }
  }
`;

export default function ImageValidationPage() {
  const [image, setImage] = useState<string | undefined>("");
  const [uploadFileaaa] = useMutation<
    Pick<IMutation, "uploadFile">,
    IMutationUploadFileArgs
  >(UPLOAD_FILE);
  const onChangeFile = async (event: ChangeEvent<HTMLInputElement>) => {
    // 배열도 어느정도 배열의 속성을 가지고 있기 때문에 .을 붙여서 ?를 붙인다.
    const file = event.target.files?.[0];
    console.log(file);
    // early exit

    const isValid = checkFileValidation(file);
    if (!isValid) return;

    try {
      const result = await uploadFileaaa({
        variables: {
          file: file,
        },
      });
      console.log(result.data?.uploadFile.url);
      setImage(result.data?.uploadFile.url || "");
    } catch (error) {
      alert(error.message);
    }
  };
  return (
    <div>
      <input type="file" onChange={onChangeFile} multiple />;
      <img src={`https://storage.googleapis.com/${image}`} />
    </div>
  );
}

 


 

이미지 용량 검증하기

 

사이즈를 알기 쉽게 비교하는 방법은 1 * 1024 * 1024 를 이용하는 것입니다.

*1 * 1024 10241MB

*5 * 1024 1024 5MB 입니다.

export const checkFileValidation = (file: File | undefined) => {
  // file:File | undefined 또는 file?이렇게 해도 됨!
  if (!file?.size) {
    alert("파일이 없습니다.");
    return false;
  }
  // 메가바이트 키로바이트 바이트     0 꺼짐  1 켜짐 2개를 가지고서 조건들을 만들다 보니
  // 컴퓨터는 1024를 기준으로 지정을 한다.
  if (file.size > 5 * 1024 * 1024) {
    alert("파일 용량이 너무 큽니다. (제한: 5MB)");
    return false;
  }

  if (!file.type.includes("jpeg") && !file.type.includes("png")) {
    alert("jpeg 파일 또는 png 파일만 업로드 가능합니다!!");
    return false;
  }

  return true;
};

 

 

 

 

 


Reference

 

댓글