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

smith_94·2022년 6월 14일
0

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

오늘은

그래프와 이미지를 압축 파일로 다운로드하는 방법이다.
다운로드할 파일은 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개의 댓글