그냥 살기 - 이미지 압축 다운로드

smith_94·2022년 6월 14일

오늘이 어쩌고 내일이 저쩌고 포기했다.
그냥 살기로 결정했다.

오늘은

그래프와 이미지를 압축 파일로 다운로드하는 방법이다.
다운로드할 파일은 Apache ECharts와 PC에 있는 이미지를 사용했다.
압축에는 JSZip를 사용했다.
내가 보려고 메모하는 게 목적이라 코드에 대한 자세한 설명은 생략한다.

test.component.html

  • 그래프 이미지 다운로드
<button (click)="imageDownload('canvas')">Download</button>

<article #canvas>
  <section *ngFor="let chart of [1, 2, 3, 4, 5]">
    <div echarts [options]="chartOption"></div>
  </section>
</article>

그래프를 컴포넌트로 분리하고 *ngFor 디렉티브와 @Input 데코레이터를 사용하면
하나의 그래프 컴포넌트로 여러 개의 데이터를 출력할 수 있다.

  • 일반 이미지 다운로드
<button (click)="imageDownload('img')">Download</button>

<article #image>
  <section>
    <img src="../content/image/tiger1.jpg" alt="tiger1">
    <img src="../content/image/tiger2.jpg" alt="tiger2">
  </section>
</article>

test.component.ts

  chartOption: EChartsOption = {};
  container = new Map;

  @ViewChild('canvas') canvas! : ElementRef;
  @ViewChild('image') image!: ElementRef;

  constructor() {}

  ngOnInit(): void {
    this.createChart();
  }

  ngAfterViewInit(): void {
    this.container.set('canvas', this.canvas);
    this.container.set('img', this.image);
  }
  
  createChart(): void {...}
  
  imageDownload(type: string): void {
    const zip = new JSZip();
    const targetImages = this.container.get(type).nativeElement.getElementsByTagName(type);

    for (let i = 0; i < targetImages.length; i++) {
      let canvas = targetImages[i];
      let fileName = `image_${i+1}.jpg`;
      if (type === 'img') {
        fileName = `${canvas.alt}.jpg`;
        canvas = document.createElement('canvas');
        canvas.width = targetImages[i].width;
        canvas.height = targetImages[i].height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(targetImages[i], 0, 0);
      }
      const url = canvas.toDataURL('image/*');
      const base64 = url.replace(/^data:image\/[a-z]+;base64,/, "");
      zip.file(fileName, base64, {'base64': true});
    }

    zip.generateAsync({type: 'base64'}).then(
      file => {
        const link = document.createElement('a');
        link.setAttribute('href', 'data:application/octastream;base64, '+ file);
        link.setAttribute('download', 'example.zip');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    )
  }

두 번 쓰기 번거로워 한 번에 정리했다.
혹시나 개발에 참고한다면 잘 구분하고 수정해서 사용할 것을 권장한다.


	// canvas background color setting, 설정하지 않으면 배경이 투명하게 나오는 경우가 있음
    const ctx = canvas.getContext('2d');
	ctx.globalCompositeOperation = 'color-burn' || 'destination-atop' || 'destination-over';
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

0개의 댓글