이미지 처리

김무연·2023년 12월 10일
0

Frontend

목록 보기
12/12
post-thumbnail

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

이미지의 처리과정을 이해하기 위해서는 storage가 무엇인지 알아야 합니다.

일반적으로 데이터베이스에는 사진을 저장하진 않습니다. 왜냐하면 파일이기 때문에 문자열과는 다르게 용량이 큽니다. 따라서 DB에 저장할 경우 용량이 부족하거나 과도한 요금이 청구될 수 있습니다.

그래서 브라우저에서 uploadFile api를 통해 벡엔드에서 클라우드(AWS, GCP, Azure == Cloud Provider)로 저장을 시킵니다. 클라우드 즉 대용량 저장창고 (storage)에 대신 사진을 업로드를 해 저장을 시켜줍니다.

이후 클라우드에 저장된 사진을 다운받을 수 있는 다운로드URL을 AWS에서 백엔드로 보내주게 되면 벡엔드 서버는 그 URL을 브라우저에 보내는 방식으로 사진을 보여줍니다.

다음 프론트 서버에서 URL을 다시 백엔드에 다른 data들과 함께 다시 보내줘서 DB에 저장이 되도록 하는 과정입니다.

이미지의 원리

결국 모든 칸을 숫자로 바꿔서 문자로 변경가능하기 때문에 문자가 엄청나게 길어져서 용량이 크게 됩니다.

파일 업로드

기본적으로 파일 업로드는 input type=”file” 로 지정한다.

<input type="file"></input>
<input type="file" />
<input type="file" multiple/>

multiple란 속성이 있으면 다중 선택 가능, 저 옵션이 없으면 클릭이 하나밖에 안됨

event.target.files?.[0]

이렇게 배열앞에도 옵셔널 체인지 가능

객체에서 key와 value가 같은것을 shorthand property라고 함

ctrl + i 누르면 뭘 선택할수 있는지 나옴

apollo로 upload를 하기 위해서는 라이브러리 설치 필요

apollo-upload-client 설치 후

app.tsx에서 바꿔 줌

import { ApolloClient, InMemoryCache, ApolloProvider, ApolloLink } from "@apollo/client";
import {createUploadLink} from 'apollo-upload-client'

interface IApolloprops {
    children: JSX.Element
}

export default function ApolloSetting(props: IApolloprops): JSX.Element {
  const uploadLink = createUploadLink({
    uri: "http://backend-practice.codebootcamp.co.kr/graphql",
  });
  const client = new ApolloClient({
    link: ApolloLink.from([uploadLink]),
    cache: new InMemoryCache(), // 컴퓨터의 메모리에다가 백엔드에서 받아온 데이터 임시로 저장해 놓기
  });

  // prettier-ignore
  return (
    <ApolloProvider client={client}>
        {props.children}
    </ApolloProvider>
    )
}

이후

import { gql, useMutation } from "@apollo/client"
import type { IMutation, IMutationUploadFileArgs } from "../../../src/commons/types/generated/typed";
import { useState } from "react";

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

export default function ImageUploadPage(): JSX.Element {
  const [image, setImage] = useState("")
  const [uploadFile] = useMutation<Pick<IMutation, "uploadFile">, IMutationUploadFileArgs>(UPLOAD_FILE);

  const onChangeFile = async (event: React.ChangeEvent<HTMLInputElement>): Promise<void> => {
    const file = event.target.files?.[0] // 배열로 들어오는 이유: <input type="file" multiple /> 일때 여러개 드래그 가능
    console.log(file)

    const result = await uploadFile({
      variables: {
        file
      }
    })
    console.log(result.data?.uploadFile.url)
    setImage(result.data?.uploadFile.url?? "")
  }
  return (
    <>
      <input type="file" onChange={onChangeFile} multiple/>
      <img src={`https://storage.googleapis.com/${image}`} />
    </>
  )
}
profile
Notion에 정리된 공부한 글을 옮겨오는 중입니다... (진행중)

0개의 댓글