[Electron] 8.검색 기능 구현(2): 이미지 설정(Buffer to Data URL) - 레시피 일렉트론 앱

검색 기능 및 결과 화면 정의

  1. 검색어를 입력하고, 컬럼을 선택해 제출하면 검색 결과 목록을 표시한다.
  2. 레시피는 한 페이지에 10개 표시하며, 페이지 버튼 또한 10개씩 표시하고 하단 부에 위치시킨다.
  3. 검색 결과 목록의 각 레시피는 이미지, title, ingredients, 다운로드 버튼, 상세 보기 버튼을 포함한다. (id, instrunctions 제외)
  4. ingredients 컬럼 값의 개수(배열 크기)가 3개 이상일 때는 값 목록을 접고 펼치도록 한다. (추가)

이전 게시물에서 작성했던 검색 기능 및 결과 화면 정의에서 3번까지 구현했지만, 모두 기능이 빠져있는 빈 이미지와 버튼들이었다. 이미지 src는 없고, 버튼은 작동하지 않는다. 가장 먼저 img 태그의 src 속성을 채워서 이미지를 표시해보겠다.

이미지 쿼리문

//rcp_sqilte_db.js
selectRcpImageFileById(id) {
        if (this.db == null)
            return '';

        const result = this.db.prepare(
            `
            SELECT id, image_file
            FROM tb_recipe
            WHERE id = ${id} 
            `
        ).all();

        return result;           
}

image_file 필드는 Fts 테이블에 등록하지 않았던 컬럼이므로, 원본 레시피 테이블(tb_recipe)에서 가져와야한다. id로 image_file을 SELECT 하는 쿼리문을 작성한다.

이미지 표시 기능 구현

이전 검색 기능 구현과 마찬가지로 preload.js, rcp_ipc.js (main), renderer.js (renderer) 내에 기능을 구현한다.

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('apis', {
		...
    req_rcpImageSrc: (id) => ipcRenderer.send('req_rcpImageSrc', id),
    resp_rcpImageSrc: (imageResult) => ipcRenderer.on('resp_rcpImageSrc', imageResult),

});

preload.js: renderer에서 사용할 ipc 함수를 (송신, 수신) window 전역 변수에 설정한다.

//rcp_ipc.js
...
addRcpimageSrc() {
        ipcMain.on('req_rcpImageSrc', (event, id) => {
            try {
                let imageResult = this.db.selectRcpImageFileById(id)[0];
                imageResult.image_file = nativeImage.createFromBuffer(imageResult.image_file).toDataURL();
                event.reply('resp_rcpImageSrc', imageResult);

            } catch (error) {
                console.log(error);
                event.reply('resp_rcpImageSrc', 'error');
            }

        });    
}
...

rcp_ipc.js: main에서 renderer 측 송신에 대한 응답 리스너를 생성한다. 응답 시에 sqlite 쿼리문을 호출하여 DB로 부터 결과를 받아서 renderer로 응답한다.

단, 받은 결과의 image_file 값은 buffer에서 dataURL 로 변환해야한다. buffer가 아닌 문자열로 변환해야 이미지의 src로 사용할 수 있다. Electron의 nativeImage 모듈을 사용하여 buffer를 DataURL로 변환한다.

/**
 * A function that requests images based on search results
 */
function displayRcpImage() {
    let idList = $('.link_img');
    $.each(idList, (key, value) => {
        let rcpId = value.id.substring(4, value.id.length);
        window.apis.req_rcpImageSrc(rcpId); //Request images to the main process
    });
}

/**
 * A listener that receives a response to images request 
 * and displays the images.
 */
window.apis.resp_rcpImageSrc((event, imageResult) =>  {
    let id = imageResult.id;
    let imageSrc = imageResult.image_file;
    $(`#img_${id}`).attr('src', imageSrc); //display
});

renderer.js:

  • 송신: 각 이미지 태그의 id를 파싱하여 main으로 이미지를 요청한다.
  • 수신: id의 img 태그 src 속성에 DataURL로 변환한 이미지 데이터를 설정해준다.

결과 화면

사진1. 레시피 일렉트론 앱 검색 결과 화면 (프로토타입)