Page tree
Skip to end of metadata
Go to start of metadata
server.js
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const fs = require('fs');
const path = require('path');
const multer = require('multer');

const ROOT_DIR = path.resolve(__dirname, '..'); // 프로젝트 Root 경로
const FILE_UPLOAD_DIR = path.resolve(ROOT_DIR, 'tmp/files'); // OCR을 하기 위한 원본 파일이 저장될 위치
const OCR_RESULT_DIR = path.resolve(ROOT_DIR, 'tmp/work'); // OCR 처리된 이미지를 저장할 위치

const OCR_API_URL = ''; // OCR API URL
const OCR_API_KEY = ''; // OCR API Key
const OCR_OPTIONS = {
    type: 'upload',
    coord: 'origin',
    skew: 'image',
    boxes_type: 'all',
    save_mask: 'true',
    textout: 'true',
    recog_form: 'true',
    extract_table: 'true'
};

const app = express();
const router = express.Router();
const uploader = multer({ dest: FILE_UPLOAD_DIR });

router.post('/request', uploader.single('file'), async (request, response) => {
    const page = (request.body || {}).page || 0;
    const file = request.file;
    const filePath = file.path;
    const originalName = file.originalname;
    const mimeType = file.mimetype;
    const extension = path.extname(originalName).split('.')[1] || mimeType.split('/')[1];
    const filePathWithExt = filePath + '.' + extension;

    fs.renameSync(filePath, filePathWithExt);
    try {
        const ocrResult = await requestOCR(filePathWithExt, page);
        const imagePath = await downloadImage(ocrResult.result.masked_image);
        response.end(JSON.stringify({ result: ocrResult.result, imagePath }));
    } catch (error) {
        response.status(error.status).send(error.message);
    }
});

/**
 * OCR을 하기위해 서버로 요청합니다.
 * @param {string} imgPath
 * @param {number} page
 * @returns 
 */
function requestOCR(imgPath, page) {
    return new Promise((resolve, reject) => {
        const options = {
            url: `${OCR_API_URL}/ocr`,
            formData: {
                api_key: OCR_API_KEY,
                image: fs.createReadStream(imgPath),
                page_index: page,
                ...OCR_OPTIONS
            }
        };

        request.post(options).on('response', response => {
            const statusCode = response.statusCode;
            const statusMessage = response.statusMessage;
            if (statusCode === 200) {
                console.log('OCR 성공');
                let body = [];
                response.on('error', (err) => {
                    throw err;
                }).on('data', (chunk) => {
                    body.push(chunk);
                }).on('end', () => {
                    resolve(JSON.parse(Buffer.concat(body).toString()));
                });
            } else {
                console.log('OCR 실패', statusCode);
                const error = new Error(statusMessage);
                error.status = statusCode;
                reject(error);
            }
        });
    });
}

/**
 * OCR 결과 이미지를 다운로드 합니다.
 * @param {string} fileName
 * @returns
 */
function downloadImage(fileName) {
    return new Promise((resolve, reject) => {
        const options = {
            url: `${OCR_API_URL}/out/${fileName}`,
            formData: {
                api_key: OCR_API_KEY,
            }
        };

        const imagePath = path.resolve(OCR_RESULT_DIR, fileName);
        request.post(options).on('response', response => {
            const statusCode = response.statusCode;
            const statusMessage = response.statusMessage;
            if (statusCode === 200) {
                console.log('OCR image download 성공');

                let imageData = Buffer.from([]);
                response.on('data', (chunk) => {
                    imageData = Buffer.concat([imageData, chunk]);
                }).on('end', () => {
                    const relativeImagePath = '/' + path.relative(ROOT_DIR, imagePath).replace(/\\/g, '/');
                    fs.writeFileSync(imagePath, imageData); // 이미지 저장
                    resolve(relativeImagePath);
                });
            } else {
                console.log('OCR image download 실패', statusCode);
                const error = new Error(statusMessage);
                error.status = statusCode;
                reject(error);
            }
        });
    });
}

app.use(bodyParser.json());
app.use('/', router);
app.listen(8080);
  • No labels