kone
코딩해요
코딩해요

서버의 디스크 공간을 사용하지 않는 신개?념 이미지 공유 api

06/17/2025, 16:16:44
PY
3219 views · -1 like
import base64
import zstd
from fastapi import FastAPI, File, UploadFile, Request, HTTPException, Response
from fastapi.responses import PlainTextResponse

app = FastAPI()

def get_media_type_from_bytes(data: bytes) -> str:
    if data.startswith(b'\x89PNG\r\n\x1a\n'): return 'image/png'
    if data.startswith(b'\xff\xd8'): return 'image/jpeg'
    if data.startswith(b'GIF87a') or data.startswith(b'GIF89a'): return 'image/gif'
    if data.startswith(b'RIFF') and data[8:12] == b'WEBP': return 'image/webp'
    return 'application/octet-stream'

@app.post("/upload",
         summary="이미지를 압축 후 URL-Safe Base64로 인코딩",
         response_class=PlainTextResponse)
async def upload_safe_image(request: Request, file: UploadFile = File(...)):
    image_bytes = await file.read()
    compressed_bytes = zstd.compress(image_bytes, 22)
    
    safe_b64_bytes = base64.urlsafe_b64encode(compressed_bytes)
    safe_string = safe_b64_bytes.decode("utf-8")
    
    image_url = request.url_for('get_safe_image', safe_string=safe_string)
    return PlainTextResponse(content=str(image_url))

@app.get("/i/{safe_string}", 
         summary="URL-Safe Base64 문자열을 디코딩/압축 해제하여 이미지 제공")
async def get_safe_image(safe_string: str):
    try:
        b64_bytes = safe_string.encode("utf-8")
        compressed_bytes = base64.urlsafe_b64decode(b64_bytes)
        
        decoded_image_bytes = zstd.decompress(compressed_bytes)

    except (ValueError, TypeError, zstd.ZstdError) as e:
        raise HTTPException(status_code=400, detail=f"잘못된 데이터 형식입니다: {e}")

    media_type = get_media_type_from_bytes(decoded_image_bytes)
    return Response(content=decoded_image_bytes, media_type=media_type)


  • 단점

    1
-1
7 comments
06/18/25 Edited 06/18/25
텍스트는 디스크 공간을 사용하는가?
06/20/25
이 이게 뭐임..?
06/30/25
base64 은근 마니 씀!
07/02/25
ㄱㅅ
11/27/25
대신 디비를 더 크게 잡아먹고, 디비 데이터 역시 디스크 용량을 잡아먹지. 오히려 파일 스토리지보단 디비가 더 비싼 자원이니까 걍 파일로 저장하는게 낫지 않으려나. 특히 게시물 검색 효율을 떨어뜨리는 문제가 있어서. 게다가 파일은 cdn으로 전송 효율을 올리기도 좋고.