- 전체
- 명
- 오늘 찾아주신 분
- 명
에서는 PDFium 에서 비트맵 렌더한 데이터를 libpng 를 사용하여 PNG 파일로 추출해보았는데, 생각해보니 다른 이미지 파일들까지 함께 처리하느라 C++ 에서 대표적으로 사용되어진다는 boost 라이브러리의 gil 기능을 사용하고 있어서, 'gil 로도 PNG 파일을 만들 수 있는데 libpng 로 이걸 쓸 필요 있을까?' 했다.
그래서 먼저, 구글링으로 찾아본 게 PDFium 과 boost::gil 을 함께 사용한 경우가 있는 지 확인해 보았다. 그러나.. 그런건 1도 없었다는거 ㅠㅠ. 같은 boost::gil 에도 libpng 를 사용하는데 왜 이런 경우를 다룬 StackOverflow 는 없을까 하며 소스를 일일히 뒤지며 공통점을 찾아보았는다.
겨우 찾아낸 것은 다행히도 이미지 버퍼 형식은 uint8_t(=unsigned char) 형식이라는 것이었다. 그렇다고하면 gil 의 이미지 구조에 잘 삽입하면 될 것 같다고 생각했다.
우선 PNG 이기 때문에 gil 에서는 알파값도 다루는 "rgba8_image_t" 이미지 구조를 사용하고 있었고, 여기에 대입해보자 해서 raw buffer 를 넣어서 초기화 할 수 있는 곳이 어디 있나 찾아보았다. 그러나 일단 C++ 초짜라 typename 으로 도배된 이것들을 해석할 능력이 되지 못했다. 어딘가에 있겠지만 못찾는게 확실 할 것이다.
대신에 구글링중에 unsigned char 형을 버퍼로 받는 interleaved_view 라는 것을 발견하게 되었다. raw data 를 써있는다고 하고 width/height 와 rowBytes 를 설정하는 곳이 있어서 이 메소드를 이용하면 복사 가능하겠다고 생각을 해서 도전을 해보았다.
그래서, 저번 포스팅에서 작성한 소스 중에..
// Include 했다...
#include <boost/gil.hpp>
#include <boost/gil/image.hpp>
#include <boost/gil/extension/io/png.hpp>
int main(){
const char *path = PDF_FILE_PATH;
int indexToLoad = 0; // 열고 싶은 페이지 인덱스 (0 번부터 1페이지이다)
// PDFium 을 초기화한다. 이걸 해야 사용할 수 있음
FPDF_InitLibrary();
// PDF 파일을 연다
FPDF_DOCUMENT doc = FPDF_LoadDocument(path, NULL);
/////////////////////////////////////
// .... 페이지를 열어 렌더했다 ....
/////////////////////////////////////
int width = FPDFBitmap_GetWidth(panel.get());
int height = FPDFBitmap_GetHeight(panel.get());
int rowBytes = FPDFBitmap_GetStride(panel.get());
uint8_t *bitmap = static_Cast<uint8_t*>(FPDFBitmap_GetBuffer(panel.get());
FPDF_CloseDocument(doc);
FPDF_DestroyLibrary();
// --------- 여기까지 완료 PDFium 으로 불러왔다
auto view = interleaved_view(width,
height,
(boost::gil::rgba_pixel_t const *) &bitmap[0],
rowBytes); // 이 아이는 boost::gil::rgba8c_view_t 형이다
// PNG 파일로 작성한다.
boost::gil::write_view("result.png", view, boost::gil::png_tag{});
// 압축옵션을 주고싶다면,
/*
boost::gil::write_view("result.png",
view,
boost::gil::image_write_info<boost::gil::png_tag>(
PNG_COMPRESSION_TYPE_DEFAULT, // 컴프레션 타입인데, 딱히 프리셋은 없는 듯하다.
3 // 압축률을 설정하는데 0-9 까지 있고 보통 3-6 을 쓰나보다. boost 기본값은 '3'
, ... // 기타 옵션은 image_write_info 참조하면 나와있다.
));
*/
}
다행히 uint8_t 버퍼가 rgba_pixel_t 로 캐스팅이 가능해서 image 구조객체는 아니지만 view 객체로 받아서 PNG 파일로 간단하게 만들 수 있었다.
boost 에서 알아서 PNG 를 처리해주니 무지 간편했다 (찾아서 쓰기도 어려운데 많은 일을 덜어내주었다).
물론 다른 방법도 있고 할 테지만 정말 C++ 은 토나와서 도저히 무슨 말인지 모르겠어서 일단 되는 대로 개발해보고 좀 더 C++ 에 대한 해독력이 늘어간다면 리팩하는걸로 스킵해본다.
[Linux] PHP Composer 다른 방식으로 설치하기 (무설치) (0) | 2022.03.14 |
---|---|
[Linux] Nginx 소스 컴파일 (베껴)설치하기 (0) | 2022.03.10 |
[Linux] 자주 쓰는 커맨드 모음 (0) | 2022.03.08 |
[Windows] PDFium 를 이용한 PDF to PNG (0) | 2022.02.04 |
[Windows] PDFium Windows DLL 추출하기 (0) | 2022.02.04 |