[Javascript] 이미지 및 텍스트 데이터 (+ 바코드 생성 데이터) 를 통합하여 하나의 데이터로 canvas 화

2024. 11. 12. 13:38기술 창고/Javascript

728x90
SMALL

개발 중인 프로젝트 내에서 특정 텍스트, 바코드를 포함한 쿠폰 이미지를 생성하여 노출시킨 후, 다운로드 할 수 있는 기능을 구현해야 했습니다.

단, 바코드와 쿠폰 이미지, 특정 텍스트 모두 각자 별개의 데이터로 이루어져있기 때문에 이것들을 적절하게 배치하여 하나의 이미지로 만든 뒤 이것을 다운로드 처리하는 것이 필수 과정이기 때문에 우선 이 요소들을 하나의 데이터로 합친 뒤 다운로드 하게끔 하는 방법에 대해서 정리해보도록 하겠습니다.

 

# 타임리프를 사용했기 때문에 th 문법이 적용되어있습니다.

 

 

HTML

<div class='col-12 couponImg' id="captureCoupon">
    <!-- 하나로 만들 canvas 쿠폰 노출 영역 -->
    <canvas id="canvas" style="width: 100%;"></canvas>
    
    <!-- 하나로 합칠 요소 1 : 쿠폰 이미지 주소 경로 -->
    <input type="hidden" id="getCouponImg" th:value="${detailInfo.getTemplateImgHostCdn() + detailInfo.getTemplateImgPathCdn() + '/' +  detailInfo.getTemplateImgName}">
    <!-- 하나로 합칠 요소 2 : 쿠폰 유효 기간 텍스트 -->
    <input type="hidden" id="expiredEndDate" th:value="${#strings.substring(detailInfo.getExchangeEndDate(), 0 ,10)}">
    <!-- 하나로 합칠 요소 3 : 바코드 생성 쿠폰 번호 -->
    <input type="hidden" th:value="${detailInfo.getCouponNumber()}" id="barcodeNumber">
</div>

 

우선 최종 쿠폰 이미지가 생성되어 노출될 canvas 영역을 만들어줍니다.

아래의 input 타입 데이터들은 이 canvas 영역에서 하나로 합쳐질 각각의 데이터들입니다.

 

 

Javascript

window.onload = function () {
    // (1)
    // 쿠폰 캔버스 영역 호출
    const canvas = document.getElementById('canvas');
    // 캔버스 context (종합적으로 캔버스에 작업할 context 영역)
    const ctx = canvas.getContext('2d');
    
    // (2)
    // 하나로 합쳐질 쿠폰 이미지 생성용 객체
    const image = new Image();
    
    // (3)
    // 서버에서 가져올 쿠폰 이미지 경로 값을 새로 생성한 이미지의 src로 적용
    image.src = document.getElementById('getCouponImg').value;
    // cors 이슈 anonymous 처리
    image.crossOrigin = "anonymous";

    // (4)
    // 새롭게 불러온 이미지가 호출될 때 캔버스 및 context 동작 처리
    image.onload = function () {
        // (5)
        // 캔버스의 너비, 높이를 호출한 이미지에 맞춘다.
        canvas.width = image.width;
        canvas.height = image.height;

        // (6)
        // 캔버스 context에 우선 첫번째로 배경이 될 호출한 이미지를 가져와 그린다.
        ctx.drawImage(image, 0, 0);

        // (7)
        // 캔버스 context의 노출 폰트 및 색상 지정
        ctx.font = "20px Arial";
        ctx.fillStyle = "black";

        // (8)
        // 하나로 합쳐질 추가 데이터들을 호출
        const expiredEndDateText = document.getElementById("expiredEndDate").value; // 유효기간 텍스트
        const barcodeNumber = document.getElementById('barcodeNumber').value; // 바코드 생성 쿠폰 번호
        
        // (9)
        // 쿠폰 번호로 만들어질 바코드가 적용될 새로운 canvas 생성
        const barcodeCanvas = document.createElement('canvas');

        // (10)
        // 캔버스 context에 우선 유효기간 텍스트 데이터를 현재 캔버스의 높이, 너비에 맞춰 적용
        ctx.fillText(expiredEndDateText + '까지', canvas.width / 3.7, canvas.height - 275);

        // (11)
        // 새로 생성한 바코드 전용 캔버스에 쿠폰 번호를 사용하여 바코드를 만든다.
        JsBarcode(barcodeCanvas, barcodeNumber, {
            format: "CODE128",     // 바코드 형식 (예: CODE128)
            width: 2,              // 바코드 막대 너비
            height: 70,            // 바코드 높이
            displayValue: true     // 텍스트 표시 여부 (바코드 밑에 노출될 쿠폰 번호)
        });

        // (12)
        // 새로 생성한 바코드 전용 캔버스의 x축, y축을 계산
        const barcodeX = canvas.width / 2 - barcodeCanvas.width / 2;  // X 위치 조정
        const barcodeY = canvas.height - 180;                         // Y 위치 조정

        // 최상위 캔버스에 바코드 전용 캔버스를 계산한 x축, y축을 이용하여 배치 후 그리기
        ctx.drawImage(barcodeCanvas, barcodeX, barcodeY);
    }
}

 

javascript 로 이미지 및 바코드, 텍스트 데이터들 처리 로직을 만들어 줍니다.

위에 작성한 로직을 기반으로 과정을 정리해보자면,

 

(1) HTML 구조로 만들어진 canvas 영역을 호출하고, 해당 canvas 영역의 2d context 생성

(2) 하나로 합쳐진 이미지들로 만들어질 새로운 image 객체 생성

(3) 새롭게 생성한 image 객체의 src 경로에 우선 바탕이 될 호출한 이미지의 호출 경로로 적용

(4) image가 적용된 src를 통해 onload 될 때 실행될 캔버스 및 바코드 관련 처리 로직 작성

(5) 최상위 canvas의 높이와 너비를 새롭게 생성한 image에 맞춘다.

(6) image를 우선적으로 canvas context에 그려준다.

(7) 이후에 적용될 텍스트 및 바코드 데이터들을 위해 context의 폰트 및 색상을 설정해준다.

(8) 추가로 합쳐질 텍스트, 쿠폰 번호 데이터들을 호출

(9) 특히 쿠폰 번호의 경우 바코드로 변환하여 넣어줄 것이기 때문에 바코드 전용 canvas 를 생성

(10) context에 우선 유효기간 텍스트 데이터를 canvas 기준으로 위치를 높이, 너비 위치를 지정하여 fillText로 넣어준다.

(11) import한 JsBarcode 라이브러리를 통해 9번 항목에서 새롭게 생성한 바코드 전용 canvas에 호출한 쿠폰 번호를 넣어 바코드로 변환하여 적용해준다.

(12) 바코드가 생성된 canvas를 최상위 캔버스의 context 를 기준으로 너비, 높이 위치를 적절히 잡아 drawImage 하여 넣어준다.

 

 

결과

정상적으로 여러 데이터를 합쳐 canvas화된 결과를 확인할 수 있습니다.

여기서 쿠폰 이미지, 유효 기간 텍스트 데이터, 바코드 데이터 이 세가지를 활용하여 canvas화 했다는 것을 다시 한번 더 확인할 수 있습니다.

 

!! 여기서 중요한 것은 canvas에 직접적으로 데이터를 적용시키는 것이 아니라 canvas의 2d context를 호출하여 그곳에 작업한 뒤 적용하는 것입니다.

728x90
반응형
LIST