ImageUs-이미지서버

codakcodak·2023년 3월 2일
0

ImageUs

목록 보기
12/17
post-thumbnail

문제상황

  • ImageUs프로젝트의 서비스는 개인의 이미지 클라우드를 제공하는 것이기 때문에 이미지를 저장하는 및 다운하는 서버가 따로 필요한데 AWS의 s3나 네이버의 사진클라우드를 이용 할 수 있지만 자칫 관리를 잘못하면 비용이 들 수 있다.

  • 일반적인 백엔드 서버와 이미지 서버를 합쳐서 구동 할 경우 한 서버가 에러가 났을 때 둘 다 기능을 상실 할 수 있다.

해결방법

  • 이미지를 업로드하고 다운로드 할 수 있는 이미지 서버를 구축한다.
  • 이미지를 편집하고 저장하는 기능이 편리한 python의 flask로 구축한다.

적용과정

  • 이미지 저장 폴더구조

*images라는 폴더에 개인 유저의 id이름의 폴더를 만들고 그 안에 유저의 사진들을 저장

  • route

    BackServer

    • POST /room/room_id/image (방에 이미지 업로드)
      header:'Authorization'
      file:'image'

      res: json

      {
          "image_info": {
            "id": 3,
            "link": "30/example3.jpg",
            "user_id": 2,
            "created_at": "2023-01-01 10:10:10 UTC+09:00"
          },
          "success": 3
      }
    • POST /image (이미지 업로드)
      header:'Authorization'
      file:'image'

      res: json

      {
          "image_info": {
            "id": 3,
            "link": "30/example3.jpg",
            "user_id": 2,
            "created_at": "2023-01-01 10:10:10 UTC+09:00"
          },
          "success": 3
      }

    ImageServer

    • POST /upload/user_id (유저의 이미지 업로드)
      header:'Authorization'
      file:'image'

      res: text(image의 다운로드 링크)

      30/example3.jpg
    • GET /image-download/user_id/filename (특정 사진 다운로드)
      header:'Authorization'

      res: image_file

  • 전체 구조

BackServer에 유저가 로그인 했을 때 받은 access_token과 함께 이미지를 업로드 하는데 BackServer에 저장된 이미지 업로드를 위한 secret_key로 토큰을 만들어 ImageServer에 같이 보내고 있다
이미지를 업로드 하려면 BackServer를 반드시 거쳐야 하고 유저가 ImageServer에 직접 업로드 하는 것을 막는다.

  • ImageServer의 파일 저장 방법(일부 코드)
    def save_profile_picture(self,user_id,image):
    	#이미지의 이름 추출
        image_filename=image.filename
		#이미지를 바이트형식으로 읽기
        image=Image.open(BytesIO(image.read()))
        
        #이미지 저장 경로 설정
        image_save_dir=f"{parent_path}/{self.config['IMAGE_PATH']}/{user_id}"
		
        #이미지 저장 경로 존재 확인
        is_user_dir_exists=os.path.isdir(f"{image_save_dir}")
		
        #존재하지 않는 다면 유저를 위한 폴더 생성
        if not is_user_dir_exists:
            os.makedirs(image_save_dir)
		
        #이미지 저장 이름 설정
        image_path_and_name=f"{image_save_dir}/{image_filename}"
        
        #이미지의 파일형식과 이름 분리
        image_dir_and_name,image_ext=os.path.splitext(image_path_and_name)
		
        #중복숫자 초기설정
        uniq=1
		
        #이미지의 저장 경로 초기값 설정
        output_path=image_path_and_name
        
        #이미지의 저장 경로가 존재하지 않을 때까지 숫자를 경로에 1씩 추가
        while os.path.exists(output_path):
            output_path=f"{image_dir_and_name}({uniq}){image_ext}"
            uniq+=1

        print(output_path)
        #이미지 저장
        image.save(output_path)
        image.close()
        image_link=f"{user_id}/{output_path.split('/')[-1]}"
        return image_link

*사용자가 같은 이름으로 된 사진을 올릴 수 있기 때문에 같은 이름의 사진이라면 고유한 사진의 이름이 될때까지 이름 뒤에 숫자를 추가해 주는 형식
(sample.jpg가 존재한다면 sample(1).jpg,sample(1).jpg가 존재한다면 sample(2).jpg식으로 최종 저장 경로 결정)

profile
숲을 보는 코더

0개의 댓글