ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • sharp image rotate 문제
    JavaScript & TypeScript 2023. 3. 12. 18:00

    문제

    이미지 업로드 시 버킷에 업로드된 이미지의 너비와 높이가 데이터베이스에 저장한 이미지 객체의 너비와 높이와 일치하지 않음.

    /**
     기존 구조
    1. `sharpInstance` 생성
    2. `sharpInstance.rotate()`
    3. 버킷에 이미지 업로드
    4. `metadata.width`, `metadata.height` 를 `DB` 에 저장
    */
    
    const sharpInstance = sharp(buffer);
    
    sharpInstance.rotate();
    
    const metadata = await sharpInstance.metadata();
    
    const image = {
        // ... 
        width: metadata.width,
        height: metadata.height,
    }
    
    bucket.upload(buffer);
    database.save(image);
    • 이미지 처리는 sharp 라이브러리를 사용함.
    • 대략 위와 같은 구조로 버킷에 업로드, 이미지 정보를 데이터베이스에 저장함.
    • 데이터베이스에 저장된 width, height 의 값이 원본 이미지와 맞지 않는 문제가 있음.

    해결 과정

    1

    • 원본 이미지의 width, heightimage 객체에 할당하기 전에 sharp.roate() 사용하는데 이 함수가 작동하지 않을까 생각함.
    • 인자를 주지 않으면 exif.orientation 을 보고 auto-rotated 된다고 알고 있어서 문제가 없지 않을까 해서 auto-rotate 를 확인했는데 함수의 문제가 아닌 것 같음.

    2

    • 문서 설명을 다시 보니 이렇게 적혀있음.
      "Rotate the output image by either an explicit angle or auto-orient based on the EXIF Orientation tag."
    • 즉, 기존 코드에서 사용하는 width, height 는 그전에 rotate 를 하더라도 roated 된 이미지의 width, height 가 아니라 원본 이미지의 width, height 를 쓰고 있었음.

    결론

    width, height 를 이미지 업로드보다 먼저 사용해야 해서 직접 orientation을 보고 width, height를 사용하도록 수정

    https://sirv.com/help/articles/rotate-photos-to-be-upright/

    • orientation 이 5~8일 때 width, height 를 뒤집어주면 됨.
    const metadata = await sharpInstance.metadata();
    
    const getNormalSize = (  
      width: number,  
      height: number,  
      orientation?: number,  
    ): { width: number; height: number } => {  
      return orientation && orientation >= 5  
        ? { width: height, height: width }  
        : { width, height };  
    };
    
    const width = getNormalSize(metadata.width, metadata.heigth, metadata.orientation);
    const height = getNormalSize(metadata.width, metadata.heigth, metadata.orientation);
    
    const image = {
        // ... 
        width,
        height,
    }
    
    bucket.upload(buffer);
    database.save(image);
킹수빈닷컴