프로필 사진 변경 기능을 구현하면서, 변경할 프로필 사진을 선택하면 그 이미지로 미리보기를 보여주고 싶었다.
처음에는 blob url을 생성하여 background-image를 설정해 주었지만, URL을 없애주는revokeObjectURL()을 계속 호출해야 한다.
revokeObjectURL은 createObjectURL()을 통해 생성된 object URL을 삭제한다.
Object URL은 revokeObjectURL을 호출하기 전이나 이 URL이 생성된 document의 라이프타임이 끝나기 전까지 유효하다.
이것이 계속해서 쌓일 경우에 메모리 누수가 생길 수 있어 사용 후 URL을 제거해 주는 것이 좋다.
따라서 fileReader를 이용하여 target.result의 value값을 이미지 태그의 src속성으로 추가방법으로 돌렸다.
이는 URL방식보다 메모리를 더 많이 사용하지만, GC를 통해 해당 데이터를 사용하지 않을 때 제거된다 한다.
다만, 다시 생각해 보았을 때, 어처피 프로필 이미지 하나만 바꾸는 것이라 file 하나만 선택할텐데
더 빠르고 효율적인 createObjectURL()를 하는 것이 맞지 않나 생각이 들기도 한다.
그렇지만 반복적으로 input에서 이미지 업로드를 계속 바꾸면 또 아닌거 같기도 하는 생각이 든다...
onchange 함수 밖에 tempPath 변수 선언을 해서 그 값이 이전과 바뀔 때만 revokeObjectURL()을 호출하는 것도 방법일 듯 하다.
JavaScript도 그렇고 html/css도 처음 써봐서 용어 자체도 헷갈릴 뿐 아니라, 내가 원하는 기능을 구현하기 위해 어떤 모듈이나 함수를 써야 할지 하나하나 검색해 봐야 했다.
무엇을 써야 적절한지 정말 감이 안잡힌다... 버튼에 이미지 바꾸는 것도 이미지의 src를 쓸지 버튼의 background-image를 설정할지 왔다갔다 했던 것 같다.
일단 기능 구현을 중점으로 이것저것 시도해봤지만 많은 시행착오가 필요할 듯 하다.
<Reference>
https://github.com/SeonHyungJo/Tip-Note/issues/66
https://stackoverflow.com/questions/31742072/filereader-vs-window-url-createobjecturl
http://www.jongminjang.com/html5/file/2018/12/26/revokeObjectURL.html
시도했던 두가지 방법에 대해 설명해 보겠다.
1. createObjectURL()
const profileBtn = document.querySelector('.profile-btn');
$("#image-input").on("change", (e) => {
let f = e.target.files[0];
//이미지 파일 외 선택
if (!f.type.match("image.*")) {
alert("이미지 파일만 선택 가능합니다.");
return;
}
//최대 용량 10MB 초과
if (f.size > 10 * 1024 * 1024) {
alert("이미지 파일은 10MB 이내로 등록 가능합니다.");
return;
}
let tempPath = URL.createObjectURL(f);
profileBtn.style.backgroundImage = url(' + tempPath + ');
//URL.revokeObjectURL(f) 를 여기서 하는 경우 미리보기 이미지가 출력되지 않는다.
changeImage = true;
check_all()
});
2. FileReader()
$("#image-input").on("change", (e) => {
let f = e.target.files[0];
//이미지 파일 외 선택
if (!f.type.match("image.*")) {
alert("이미지 파일만 선택 가능합니다.");
return;
}
//최대 용량 10MB 초과
if (f.size > 10 * 1024 * 1024) {
alert("이미지 파일은 10MB 이내로 등록 가능합니다.");
return;
}
image = f;
let reader = new FileReader();
reader.onload = function(e) {
$('#button-image').attr('src', e.target.result);
}
reader.readAsDataURL(f);
changeImage = true;
check_all()
});
<Reference>
https://pm1122dev.tistory.com/38
<전체 Reference>
https://github.com/SeonHyungJo/Tip-Note/issues/66
https://velog.io/@chaeduk/%EA%B0%9C%EB%B0%9C-%EA%B8%B0%EB%A1%9D-FileReader.readAsDataURL-vs-URL.createObjectURL
https://stackoverflow.com/questions/31742072/filereader-vs-window-url-createobjecturl
http://www.jongminjang.com/html5/file/2018/12/26/revokeObjectURL.html
https://knight76.tistory.com/entry/springboo2-thymeleaf-%EC%82%AC%EC%9A%A9%ED%95%A0-%EB%95%8C-%EC%A3%BC%EC%9D%98%ED%95%A0-%EC%A0%90
https://pm1122dev.tistory.com/38
https://velog.io/@aljongjong/JavaScript-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%AF%B8%EB%A6%AC%EB%B3%B4%EA%B8%B0
https://dongyeopblog.wordpress.com/2017/09/02/javascript-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%AF%B8%EB%A6%AC%EB%B3%B4%EC%97%AC%EC%A3%BC%EA%B8%B0-preview-image-upload/
'JavaScript' 카테고리의 다른 글
[ajax] ajax로 json과 file 동시에 전송하기 (0) | 2023.02.01 |
---|