새소식

Go

Go - 이미지 리사이즈 기능(/h2non/bimg)

  • -

개요

Go로 이미지 호스팅 서버를 개발하던 중, 이미지 리사이즈 기능을 구현하는 과정에서 고민했던 점들을 정리해보았다.


go 주요 이미지 리사이즈 라이브러리 비교

라이브러리 장점 단점
bimg - libvips 기반으로 매우 빠른 처리 속도 - 메모리 사용량이 적음 - 다양한 이미지 포맷 지원 - C 바인딩으로 인한 설치 복잡도 증가 - libvips 의존성 필요 - Windows 환경에서 설정이 까다로움
imaging - 순수 Go로 작성되어 설치가 간단 - 크로스 플랫폼 지원이 용이 - API가 직관적이고 사용하기 쉬움 - 처리 속도가 상대적으로 느림 - 메모리 사용량이 많음 - 일부 고급 이미지 처리 기능 부재
nfnt/resize - 가볍고 단순한 구현 - 순수 Go로 작성되어 의존성이 없음 - 기본적인 리사이즈 기능 제공 - 성능이 상대적으로 낮음 - 고급 이미지 처리 기능 부재 - 메모리 사용량이 많음 - 지원이 종료됨
imgproxy - 다양한 이미지 처리 옵션 제공 - 캐싱 기능 내장 - 고성능 처리 - 별도의 서비스로 실행 필요 - 설정이 복잡함 - 리소스 사용량이 많음

라이브러리 선택 과정

1. 초기 고려사항
   - 순수 Go로 작성된 라이브러리 선호 (설치 간편성)
   - 기본적인 리사이즈 기능만 필요

2. 시도한 라이브러리들
   - `github.com/nfnt/resize`: 순수 Go로 작성되어 설치가 간단했으나, WebP 미지원
   - `github.com/disintegration/imaging`: 순수 Go로 작성되어 설치가 간단했으나, WebP 지원이 제한적

3. bimg 선택 이유
   - libvips 기반으로 매우 빠른 처리 속도
   - WebP를 포함한 다양한 이미지 포맷 지원
   - 메모리 효율적인 처리
   - Docker 환경에서 쉽게 설정 가능
   - 활발한 커뮤니티와 안정적인 업데이트

4. 선택 후 고려사항
   - libvips 설치 필요성
   - Docker 환경에서의 설정

webp 확장자를 지원하는 라이브러리 중 비교적 간단하게 관리할 수 있는 bimg를 선택하게 되었다.


코드를 작성하기 전에!

go 구동 환경에 libvips 설치가 필요하다.

  • macOS: Homebrew를 통한 설치
brew install vips
  • Ubuntu/Debian: apt를 통한 설치
sudo apt-get update
sudo apt-get install -y libvips-dev
  • Windows: MSYS2를 통한 설치
pacman -S mingw-w64-x86_64-libvips
  • 설치 확인
# libvips 버전 확인
vips --version

코드

Go의 github.com/h2non/bimg 라이브러리를 사용하여 이미지 리사이즈 기능을 구현했다.
이 라이브러리는 libvips를 기반으로 하여 빠른 이미지 처리가 가능하다.

import (
    "fmt"
    "log"
    "strconv"
    "strings"

    "github.com/h2non/bimg"
)

/*
이미지를 주어진 크기로 리사이징

Parameters:
  - size: "width x height" 형식의 문자열 (예: "100x100")
  - filePath: 리사이징할 이미지 파일 경로

Returns:
  - []byte: 리사이징된 이미지 바이트
  - error: 에러 발생 시 에러 객체 반환
*/
func ResizeImage(size string, filePath string) ([]byte, error) {
    // 이미지 파일 확장자 체크
    if !strings.HasSuffix(strings.ToLower(filePath), ".jpg") &&
        !strings.HasSuffix(strings.ToLower(filePath), ".jpeg") &&
        !strings.HasSuffix(strings.ToLower(filePath), ".png") &&
        !strings.HasSuffix(strings.ToLower(filePath), ".webp") {
        return nil, fmt.Errorf("지원하지 않는 이미지 형식입니다")
    }

    // size 파라미터 파싱
    sizes := strings.Split(size, "x")
    if len(sizes) != 2 {
        return nil, fmt.Errorf("잘못된 크기 형식입니다. (예: 100x100)")
    }

    width, err := strconv.Atoi(sizes[0])
    if err != nil {
        return nil, fmt.Errorf("잘못된 너비 값입니다")
    }

    height, err := strconv.Atoi(sizes[1])
    if err != nil {
        return nil, fmt.Errorf("잘못된 높이 값입니다")
    }

    // 이미지 읽기
    buffer, err := bimg.Read(filePath)
    if err != nil {
        return nil, fmt.Errorf("이미지 처리 중 오류가 발생했습니다")
    }

    // 리사이즈 수행
    newImage, err := bimg.NewImage(buffer).Resize(width, height)
    if err != nil {
        return nil, fmt.Errorf("이미지 처리 중 오류가 발생했습니다")
    }

    return newImage, nil
}

후기

라이브러리를 사용하여 이미지 리사이즈 기능 자체를 구현하는 것은 어렵지 않았으나 webp 확장자를 지원하는 라이브러리를 찾느라 조금 헤매게 되었다.
그래도 정리하고 나니 뿌듯하다.

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.