서버에서 16진수 형식의 바이너리 데이터로 이미지를 주고 있다.
첨엔 blob으로 친절하게 준다며..(요) 경로로 친절하게 준다며..(요) 16진수는 왜 나오는건데
하라면 해야지 뭐
👺(백엔드 개발자님) : "료미님 api 완성 되었어요 ~ "
💀(나) : 고생하셨어요 !! 이미지는 경로로 주시죠 ??
👺(백엔드 개발자님) : 아니요 ? 형식 잘 파악해서 넣어주세요 ~~
💀(나) : ????
89504e470d0a1a0a0000000d494844520000003c0000003c0806000000b18ece ~~
까본 형식은 이러했다.
처음에 base64 형식인 줄 알고, 열심히 인코딩 함수를 만들었다.
가능할리가 ..
찾아보다가 서버에서 전달된 데이터가 16진수로 인코딩된 바이너리 데이터라는 것을 찾아냈다
const convertBinaryToUrl = (binary: string) => {
const length = binary.length
const bytes = new Uint8Array(length / 2)
for (let i = 0; i < length; i += 2) {
bytes[i / 2] = parseInt(binary.substr(i, 2), 16)
}
Uint8Array로 변환된 바이너리 데이터를 Blob 객체로 감싸서 이미지의 데이터 타입(여기서는 'image/png')을 지정(때에 따라 jpg, jpeg도 가능하다). 이렇게 하면 브라우저가 이 데이터를 이미지 파일로 인식할 수 있게 된다.
const arrayBuffer = bytes.buffer
const blob = new Blob([arrayBuffer], { type: 'image/png' })
return URL.createObjectURL(blob)
}
const originBlobUrl = convertBinaryToUrl(origin_file.binary)
const compareBlobUrl = convertBinaryToUrl(compare_file.binary)
const resultBlobUrl = convertBinaryToUrl(result_file.binary)
이렇게 만들어진 URL은 HTML의 img 태그에 src 속성으로 설정할 수 있다.
나 같은 경우에는 상태로 관리하고 싶어서
setImages([
{
label: '원본 이미지',
src: originBlobUrl,
alt: '원본 이미지',
},
{
label: '비교 이미지',
src: compareBlobUrl,
alt: '비교 이미지',
},
{
label: '결과 이미지',
src: resultBlobUrl,
alt: '결과 이미지',
},
])
이런식으로 세팅하고 return 부분의 img src에 images.src를 map으로 돌려 3개의 이미지가 나오도록 했다.
{images.map((image, index) => (
<Section key={index}>
<ImgLabel>{image.label}</ImgLabel>
<Img src={image.src}></Img>
</Section>
))}
잘 나온다. (보안상의 이유로 가림)
고생많으셨네요..
이럴 때는 서버개발자를 따끔하게 혼내줘야합니다..
국룰대로 해야 나중에 문제가 없더라구요 (base64, presigned URL)
그리고 작성해주신 글에는 revokeObjectURL에 관한 내용이 없어서 혹시나 해서 작성합니다!
createObjectURL을 했을 경우에는 브라우저를 종료하기 전까지는 메모리를 계속 먹습니다.
revokeObjectURL로 unMount시에 처리를 해주셔야합니다.