이미지 워터마크, 저장할까 서빙할까
이미지 워터마크, 저장할까 서빙할까
카드 이미지에 워터마크가 필요했다. 두 가지 방법이 있다:
- A. 저장 시 박기: 워터마크를 영구 새김
- B. 서빙 시 찍기: 원본 유지, 요청 시마다 실시간 적용
A는 간단하지만, 디자인 변경 시 200장+ 재처리해야 하고 원본이 손상된다. 프리미엄 사용자에게 워터마크 없는 버전을 줄 수도 없다.
B(on-the-fly)를 선택했다.
구현
1
2
3
4
5
6
7
8
def add_watermark(image_bytes, text="BlessFlow", opacity=90):
img = Image.open(io.BytesIO(image_bytes)).convert("RGBA")
overlay = Image.new("RGBA", img.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(overlay)
# 우하단에 반투명 텍스트
draw.text((x, y), text, fill=(255, 255, 255, opacity), font=font)
result = Image.alpha_composite(img, overlay).convert("RGB")
return result
서빙 엔드포인트에서 raw=true 파라미터로 원본/워터마크를 선택한다.
CSS 워터마크는 왜 안 되나
처음엔 CSS ::after로 텍스트를 올려봤다. z-index 문제, 투명도 불일치, 스크린샷/다운로드 시 미적용 등 문제가 많았다. 서버에서 이미지 자체에 찍는 것이 확실하다.
비용
- 추가 저장: 0
- CPU 오버헤드: ~50ms/이미지
- 체감 지연: 거의 없음 (이미지 로딩이 더 오래 걸림)
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.