Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejava
themeEmacs
titleOcrController
linenumberstrue
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.FileInputStream;

import org.apache.commons.io.IOUtils;

@Slf4j
@RestController
public class OcrController {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final String ROOT_DIR = ".."; // 프로젝트 Root 경로
    private static final String OCR_RESULT_DIR = ROOT_DIR + "/tmp/work"; // OCR 처리된 이미지를 저장할 위치

    private static final String OCR_API_URL = ""; // OCR API URL
    private static final String OCR_API_KEY = ""; // OCR API Key

    /**
     * OCR API를 호출합니다.
     * @param file
     * @param page
     * @return
     */
    @PostMapping("/requestrequestOCR")
    public ResultModel ocrRequest(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "page", required = false, defaultValue = "0") int page) {
        ResultModel model = new ResultModel();
        model.setResult("false");

        try {
            OCRResult ocrResult = getOcrResult(file, page);
            String fileName = downloadImage(ocrResult.getMasked_image());

            String imagePath = String.format("%s/viewImage?fileName=%s", ServletUriComponentsBuilder.fromCurrentContextPath().toUriString(), fileName);
            model.setResult(ocrResult);
            model.setImagePath(imagePath);
            return model;
        } catch (IOException e) {
            log.warn(e.getMessage(), e);
            return model;
        }
    }

    /**
     * 이미지 바이트 배열을 가져옵니다.
     * @param fileName
     * @return
     * @throws IOException
     */
    @GetMapping("/viewImage")
    public ResponseEntity<byte[]> getImageByteArray(String fileName) throws IOException {
        InputStream imageStream = new FileInputStream(String.format("%s/%s", OCR_RESULT_DIR, fileName));
        byte[] imageByteArray = IOUtils.toByteArray(imageStream);
        imageStream.close();
        return new ResponseEntity<>(imageByteArray, HttpStatus.OK);
    }

    /**
     * OCR result를 반환합니다.
     * @param file
     * @param page
     * @return
     * @throws IOException
     */
    private OCRResult getOcrResult(MultipartFile file, int page) throws IOException {
        OCRResult ocrResult = requestOCR(file, page);

        if (ocrResult == null) {
            throw new IOException("OCR request failed.");
        }
        return ocrResult;
    }

    /**
     * OCR API를 호출합니다.
     * @param file
     * @param page
     * @return
     * @throws IOException
     */
    private OCRResult requestOCR(MultipartFile file, int page) throws IOException {
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        File f = new File("/C:/image/" + file.getOriginalFilename());
        file.transferTo(f);
        FileSystemResource fileSystemResource = new FileSystemResource(f);
        body.add("api_key", OCR_API_KEY);
        body.add("page_index", String.valueOf(page));
        body.add("image", fileSystemResource);
        body.add("type", "upload");
        body.add("coord", "origin");
        body.add("skew", "image");
        body.add("boxes_type", "all");
        body.add("save_mask", true);
        body.add("textout", true);
        body.add("recog_form", true);
        body.add("extract_table", true);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

        String serverUrl = OCR_API_URL + "/ocr";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.postForEntity(serverUrl, requestEntity, String.class);

        return this.objectMapper.readValue(this.objectMapper.readTree(response.getBody()).get("result").toString(), OCRResult.class);
    }

    /**
     * OCR 결과이미지를 다운로드 합니다.
     * @param fileName
     * @return
     * @throws IOException
     */
    private String downloadImage(String fileName) throws IOException {
        URL url = new URL(OCR_API_URL + "/out/" + fileName);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        String formData = "api_key=" + OCR_API_KEY;
        connection.setDoOutput(true);

        try (OutputStream outputStream = connection.getOutputStream()) {
            byte[] formDataBytes = formData.getBytes("UTF-8");
            outputStream.write(formDataBytes, 0, formDataBytes.length);
        }

        int statusCode = connection.getResponseCode();
        String statusMessage = connection.getResponseMessage();
        if (statusCode == 200) {
            System.out.println("OCR image download 성공");
            String outFilePath = String.format("%s/%s", OCR_RESULT_DIR, fileName);
            try (InputStream inputStream = connection.getInputStream();
                 FileOutputStream outputStream = new FileOutputStream(outFilePath)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }

            return fileName;
        } else {
            System.out.println("OCR image download 실패: " + statusCode);
            throw new IOException(statusMessage);
        }
    }
}

...