본문 바로가기
웹 코딩/JS + jQuery

이미지 클릭하면 다운로드 시키기

by 알릭2 2020. 8. 2.

가끔 이미지를 브라우저에 보여주는게 아니라 다운로드 시켜야 할 때가 있음

 

 

예전 같으면 숨겨진 아이프레임으로 폼을 전송해서 php를 통해 다운로드 시키는 방법을 썼겠지만 요즘엔 더 간단히 자바스크립트나 html 만으로 처리가 가능함 

 

방법 1.

<a href="이미지주소" download="파일명">
  <img src="이미지주소">
</a>

a 태그에 download 를 넣어 줌 (확장자를 제외한 파일명을 넣어 줄 수 있음. 없어도 됨)

단점은, IE, Edge, Safari, Opera 는 지원을 안한다는 점과 이미지가 사이트와 같은 도메인에 있어야 한다는 점

 

방법 2.

function dataURLtoBlob(dataurl) {
  var arr = dataurl.split(','),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], {
    type: mime
  });
}

function downloadImg(imgSrc) {
  var image = new Image();
  image.crossOrigin = "anonymous";
  image.src = imgSrc;
  var fileName = image.src.split("/").pop();
  image.onload = function() {
    var canvas = document.createElement('canvas');
    canvas.width = this.width;
    canvas.height = this.height;
    canvas.getContext('2d').drawImage(this, 0, 0);
    if (typeof window.navigator.msSaveBlob !== 'undefined') {
      window.navigator.msSaveBlob(dataURLtoBlob(canvas.toDataURL()), fileName);
    } else {
      var link = document.createElement('a');
      link.href = canvas.toDataURL();
      link.download = fileName;
      link.click();
    }
  };
}

위 두 함수를 페이지에 추가한 후 이미지 다운로드가 필요할 시 (a, img, button 등) downloadImg('이미지주소'); 가 실행되게 온클릭을 먹임

 

장점은 IE도 되고 크롬도 된다는 점

단점은 이미지를 불러와서 캔버스에 한번 다시 그린후 처리하는거라 원 이미지의 meta 정보가 없어짐

그리고 이미지가 같은 도메인에 있거나 아니면 보내주는 쪽에서 crossorigin 을 허용한 상태에서만 가능함

 

유사한 방식으로, 이미지를 불러와 캔버스에 그리는 대신 ajax 로 이미지를 호출해서 직접 blob 을 얻어와 처리할 수도 있음

(blob으로 받아왔다면 FileReader.readAsDataURL() 같은걸로 blob을 DataURL 로 바꿔줘야 할 듯, 암튼 이를 잘 응용하면 이미지뿐만 아니라 다른 파일도 다운로드 받게 할 수 있음. 이미 pdf 는 해봤음)

 

결국 핵심은 아래에서 '블롭' 과 '데이터URL' 을 적절히 채워주면 되는 것!

    if (typeof window.navigator.msSaveBlob !== 'undefined') {
      window.navigator.msSaveBlob(블롭, fileName);
    } else {
      var link = document.createElement('a');
      link.href = 데이터URL;
      link.download = fileName;
      link.click();
    }

그리고, downloadImg() 함수 내용을 이해했다면, 캔버스 이미지를 저장하는 용도로 쓸 수도 있겠음

 

댓글