January 25, 2019
사내 프로젝트 중 Spring boot로 진행하는 프로젝트의 개발을 진행하던 중 위의 기능을 개발해야 했다.
이번 포스팅에서는 Java 라이브러리 중 PDFBox를 이용하여 Pdf를 이미지로 구현하는 방법을 정리해보려 한다.
개발환경은 Mac OS 이며 Spring boot 2.0, Java8을 사용하였다.
현재 포스팅을 하는 시점에서는 2.0.13 버전을 사용하였다.
아래의 Gradle을 추가해줘야 한다.
compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.13'
compile group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.13'
Maven을 사용하시는 분은 아래를 참고하자.
<!-- PDFBox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.13</version>
</dependency>
<!-- PDFBox-Tool -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.13</version>
</dependency>
아래의 코드를 참고하자.
private List<String> conversionPdf2Img(InputStream is, String uniqueId) {
List<String> savedImgList = new ArrayList<>(); //저장된 이미지 경로를 저장하는 List 객체
try {
PDDocument pdfDoc = PDDocument.load(is); //Document 생성
PDFRenderer pdfRenderer = new PDFRenderer(pdfDoc);
String resultImgPath = "/home/dev/sample/result/"; //이미지가 저장될 경로
Files.createDirectories(Paths.get(resultImgPath)); //PDF 2 Img에서는 경로가 없는 경우 이미지 파일이 생성이 안되기 때문에 디렉토리를 만들어준다.
//순회하며 이미지로 변환 처리
for (int i=0; i<pdfDoc.getPages().getCount(); i++) {
String imgFileName = resultImgPath + "/" + i + ".png";
//DPI 설정
BufferedImage bim = pdfRenderer.renderImageWithDPI(i, 300, ImageType.RGB);
// 이미지로 만든다.
ImageIOUtil.writeImage(bim, imgFileName , 300);
//저장 완료된 이미지를 list에 추가한다.
savedImgList.add(makeDownloadUrl4Uuid(imgFileName));
}
pdfDoc.close(); //모두 사용한 PDF 문서는 닫는다.
}
catch (FileNotFoundException e) { throw new PdfNotFoundException(this, "Pdf file not found. exception message = " + e.getMessage() ); }
catch (IOException e) { throw new Pdf2ImgChangeException(this, "Change fail pdf to image. IOException message = " + e.getMessage() ); }
return savedImgList;
}
위 메서드에서 전달인자는 InputStream을 받는데 이 부분은 PDF 파일을 FileInputStream으로 넘겨주면 된다.
new FileInputStream(new File(inputPdfPath))
와 같이 처리할 수 있다.
그리고 이 메서드는 이미지를 변환한 파일의 경로를 반환하는데 이 부분은 알맞게 변환하여 사용하면 된다.
나머지 자세한 것은 주석을 참고하면 될듯 하다.