본문 바로가기

react

이미지 url로 base64 encode 값 구하기

export async function loadImage(url: string) {
    return new Promise((resolve) => {
        const img = new Image()
        img.src = url + "?timestamp=" + new Date().getTime()
        img.crossOrigin = "Anonymous"
        img.onload = () => {
            const canvas = document.createElement("canvas")
            canvas.height = img.height
            canvas.width = img.width

            const ctx = canvas.getContext("2d")
            if (ctx) {
                ctx.drawImage(img, 0, 0)

                const base64 = canvas.toDataURL()

                resolve({ height: img.height, width: img.width, src: base64 })
            }
        }
    })
}

s3 에서 이미지 가져올때 cache를 타는 경우가 있는데 timestamp 파라미터를 붙이면 해결된다

 

 

 

✏️  But.. 찾아보니 canvas.toDataURL는 이미지의 original base64 value와 다른 값을 주거나, 브라우저마다 다른 값을 리턴할 수 있다고 한다.

나의 경우에 단순 출력이 아닌 정확한 base64 값이 필요했다.

이 경우는 url -> blob -> base64로 변환하여 해결했다.

export async function loadImage(src: string) {

    const urlToFile = async (url: string) => await fetch(url).then((res) => res.blob())
    
    const blobToBase64 = (blob: Blob) => {
        const reader = new FileReader()
        reader.readAsDataURL(blob)
        return new Promise((rs, rj) => {
            reader.onloadend = () => {
                rs(reader.result)
            }
            reader.onerror = rj
        })
    }

    return new Promise((resolve) => {
        const img = new Image()
        img.src = src + "?timestamp=" + new Date().getTime()
        img.crossOrigin = "Anonymous"
        img.onload = async () => {
            const blob = await urlToFile(src + "?timestamp=" + new Date().getTime())
            const base64 = await blobToBase64(blob)
            resolve({ height: img.height, width: img.width, src: base64 })
        }
    })
}​
반응형