헤더에 Word 또는 Excel 스타일의 그라데이션 배경을 포함하는 PDF를 이미지로 렌더링하면, 색상이 혼합되어야 할 위치가 빈 흰색 사각형으로 출력되곤 했습니다. HotPDF의 페이지 렌더러는 이제 유형 2 축(Axial) 및 유형 3 방사형(Radial) 그라데이션에 대한 PDF sh (셰이딩) 연산자를 지원합니다: 그라데이션 축을 따라 셰이딩 함수를 평가하고 혼합 색상을 칠합니다. 이전 버전은 이 연산자를 조용히 무시하여 해당 영역을 종이처럼 하얗게 비워두었습니다. 거의 모든 오피스 문서 그라데이션을 커버하는 두 가지 셰이딩 유형이 도입되었으며, 메쉬(Mesh) 유형은 지원되지 않습니다. 이 기사에서는 이 한계선이 어디에 획정되어 있는지 명확히 밝힙니다
왜 PDF 그라데이션이 흰색 상자로 렌더링되나요?
PDF 그라데이션은 렌더러가 전송(Blit)할 수 있는 비트맵이 아니라 벡터 구조이기 때문입니다. 셰이딩 딕셔너리(ISO 32000-1 §8.7.4.5)는 기하학적 요소(Coords 배열의 축 또는 원의 쌍)와 색상 함수를 기술하며, sh 연산자는 현재 클립 영역 전체에 해당 셰이딩을 칠합니다. 이는 개발자가 페이지 캔버스에 경로와 채우기를 그릴 때 HotPDF가 제공하는 것과 동일한 그래픽 모델입니다. HotPDF의 페이지 렌더러는 콘텐츠 스트림을 연산자별로 순회하며, 코드 경로가 정의되지 않은 연산자는 건너뜀으로써 페이지의 나머지 부분을 계속 렌더링합니다. 버전 2.335.0 이전에는 sh가 이 건너뛰기 집합에 속해 있었습니다: 헤더나 전체 페이지 그라데이션이 출력물에 아무런 영향을 주지 못했기 때문에 배경이 흰색으로 비쳐 보였습니다. 파일 자체가 손상된 것은 아니었습니다. 단지 렌더러가 해당 연산자에 대한 핸들러를 누락했기 때문이며, 흰색 상자가 바로 누락된 핸들러로 인한 일반적인 결과물입니다
셰이딩 하부의 함수 평가 체인
함수가 평가되기 전에는 셰이딩을 칠할 수 없으므로, 해당 작동 메커니즘이 먼저 구현되어야 했습니다. 유형 2 축 및 유형 3 방사형 셰이딩은 모두 그라데이션을 따른 매개변수적 위치를 색상으로 매핑하는 /Function을 동반하며(ISO 32000-1 §7.10), HotPDF의 함수 평가기는 FunctionType을 결정하고 이를 디스패치(Dispatch)합니다. 유형 2 지수 보간(§7.10.3)은 Domain 및 Range 클램핑과 함께 C0 + t^N * (C1 - C0)을 계산합니다. 유형 0 샘플링 함수(§7.10.2)는 8, 16 또는 32비트 샘플의 그리드를 읽고 Encode 맵을 통해 가장 가까운 샘플을 선택합니다. 이는 유형 0 샘플링된 색상 룩업 분석에서 상세히 다루는 방식입니다. 유형 3 스티칭(Stitching) 함수(§7.10.4)는 Bounds 배열을 기준으로 하위 함수를 선택하고 이를 재귀적으로 처리합니다. 유형 4 PostScript 계산기 함수(§7.10.5)는 평가되지 않으며, HotPDF의 보수적인 렌더링 규칙에 따라 잘못된 색상을 인쇄하는 대신 평가 실패로 부드럽게 무시 처리됩니다. 이 평가기는 셰이딩 페인터의 성능이 하부 함수에 전적으로 의존하기 때문에, 연산자 자체보다 한 버전 앞선 버전 2.334.0에 먼저 포함되었습니다
HotPDF가 연속적인 그라데이션을 픽셀로 변환하는 방법
HotPDF는 유한한 개수의 단색 대역(Band)을 사용하여 연속적인 혼합 색상을 근사치로 채웁니다. 셰이딩 페인터는 그라데이션 축을 순회하며 이를 최대 64개의 대역(장치 해상도 기준으로 축이 짧은 경우 이보다 적은 수)으로 분할하고, 각 대역의 매개변수적 위치에서 함수를 평가한 뒤 축과 수직인 사각형을 단색 브러시로 채웁니다. 관건은 대역 수와 부드러움 간의 트레이드오프입니다: 대역이 많을수록 혼합이 부드러워지지만 채우기 비용이 늘어나며, 64개가 합리적인 상한선입니다. 대역의 개수는 장치 픽셀 단위의 축 길이와 비례하므로 해상도가 중요하게 작용합니다. 동일한 페이지를 높은 DPI로 렌더링하면 축이 길어지므로 짧은 그라데이션에 더 많은 대역이 가해져 줄무늬가 부드러워지며, 이는 최대 64개 대역 제한을 채울 때까지 계속됩니다
// 셰이딩 이산화기는 그라데이션 축을 따라 최대 64개의 색상 대역을 사용합니다
// 다만 장치 픽셀 기준의 축 길이보다 많이 나누지는 않습니다. 동일한 페이지를
// 높은 DPI로 렌더링하면 축이 길어지므로 짧은 그라데이션에 더 많은
// 대역이 생겨 64개 대역 한계까지 줄무늬가 부드러워집니다.
Thumb := Pdf.RenderLoadedPageToBitmap(PageIndex, 96); // 거친 대역
Proof := Pdf.RenderLoadedPageToBitmap(PageIndex, 300); // 최대 64개 대역
셰이딩된 페이지를 비트맵에 렌더링하기
공개 진입점은 변경되지 않았습니다: RenderLoadedPageToBitmap은 0부터 시작하는 페이지 인덱스와 DPI 값을 받아 호출자가 소유하는 24비트 비트맵을 반환하고, 실패 시 예외를 발생시키는 대신 nil을 반환하므로 기존 코드에 투명하게 셰이딩 기능이 녹아듭니다. A 페이지가 그라데이션 헤더를 빈 공간으로 렌더링하는 대신, 이제 혼합 색상이 그려진 비트맵을 반환하므로 이를 위해 API를 수정할 필요가 없습니다. 한 가지 기억해 두어야 할 점은 소유권입니다: 반환된 비트맵의 해제 책임은 호출자에게 있습니다. 전체 렌더링 파이프라인(콘텐츠 스트림 해석, 임베디드 글리프, 페이지 캐싱)은 Delphi에서 비트맵에 PDF 페이지 렌더링하기 가이드에서 다룹니다
var
Pdf: THotPDF;
Bmp: TBitmap;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('quarterly-report.pdf') > 0 then
begin
// 150 DPI 기준의 1페이지(0부터 시작). 이전에는 비어 있던
// 그라데이션 채우기 헤더가 이제 색상 혼합을 포함합니다.
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
Bmp.SaveToFile('page1.bmp');
finally
Bmp.Free;
end;
end;
finally
Pdf.Free;
end;
end;
동일한 호출을 사용해 간단한 회귀 테스트(Regression test)를 수행할 수 있습니다. 페이지를 렌더링하고, 그라데이션 대역이 있어야 할 지점의 픽셀을 추출하여 이전처럼 흰색 용지 배경으로 남아 있지 않은지 확인하십시오. 이는 이전의 무작동(No-op) 현상으로 돌아가지 않았는지 체크하는 단순한 방법입니다
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
// sh 연산자가 그려진 경우 True, 해당 영역이 흰색으로 남은 경우 False입니다.
HeaderPainted := Bmp.Canvas.Pixels[Bmp.Width div 2, 8] <> clWhite;
finally
Bmp.Free;
end;
HotPDF가 그리지 않는 것: 메쉬(Mesh) 셰이딩 및 클립 가장자리
네 가지 메쉬(Mesh) 셰이딩 유형은 범위를 벗어나며, 문서 작성 시 이 점을 감안해야 합니다. ISO 32000-1 §8.7.4.5.5부터 §8.7.4.5.8에 정의된 자유 형태 고로(Gouraud) 삼각형 메쉬(유형 4), 격자 형태 고로 메쉬(유형 5), 쿤스(Coons) 패치 메쉬(유형 6), 텐서곱(Tensor-product) 패치 메쉬(유형 7) 등은 렌더링되지 않습니다; 해당 메쉬를 사용하는 페이지 자체는 렌더링되지만, 메쉬 영역은 채워지지 않고 비어 있게 됩니다. 추가로 유념해야 할 두 가지 한계점이 있습니다. 대역 사각형들은 현재 클립 경로에 맞춰 정밀하게 정렬되기보다 셰이딩 스트라이프 영역을 덮으므로, 둥글거나 불규칙한 모양으로 마스킹된 그라데이션은 정밀 영역 클리핑이 향후 릴리즈에 도입되기 전까지 바운딩 스트라이프로 채워집니다. 또한 HotPDF는 함수 출력을 RGB 또는 그레이스케일로 가정하므로, CMYK나 특이한 색상 공간에서 작성된 셰이딩은 색상 관리 프로필을 적용하는 대신 근사치로 변환되어 표현됩니다. 대부분의 Delphi 및 C++Builder 개발팀이 실제로 다루는 문서(PDF로 내보낸 보고서, 송장, 명세서, 슬라이드 자료 등)의 경우, 축 및 방사형 그라데이션이 만나는 그라데이션의 대부분을 구성하므로 메쉬가 무겁게 사용된 설계 도면 등은 최종 인쇄 증명이 아닌 프리뷰 용도로 다루는 것이 적절합니다
HotPDF의 페이지 렌더러, 여기 설명된 sh 연산자 지원 기능, 하부의 유형 0/2/3 함수 평가기는 PDF 생성, 편집, 텍스트 추출 및 페이지 렌더링을 하나의 패키지에서 다루는 외부 DLL 의존성이 없는 네이티브 VCL 라이브러리인 Delphi 및 C++Builder용 HotPDF 컴포넌트의 일부로 제공됩니다