Os ficheiros JPEG 2000 aparecem em imagens médicas, fotos de arquivo e saída de câmaras de alta resolução. Quando esses ficheiros têm de entrar num PDF, existem duas abordagens. Pode descodificá-los para píxeis brutos e recomprimí-los como JPEG ou Flate, o que acrescenta artefactos ou aumenta o tamanho. Ou pode incorporá-los diretamente como fluxos JPXDecode, preservando os dados originais sem qualquer recodificação. O HotPDF suporta o segundo caminho. Este artigo descreve como funciona o caminho e o que é necessário saber ao utilizá-lo
JPXDecode no PDF
A especificação PDF, ISO 32000-1 §7.4.9, lista JPXDecode como um filtro de fluxo suportado a partir do PDF 1.5. Difere dos outros filtros de imagem de uma forma importante: não limita imagens bilevel, em escala de cinzentos ou RGB. O JPEG 2000 suporta qualquer número de componentes, profundidades de bits arbitrárias e mapas de cores de espaço de cor, pelo que o filtro JPXDecode pode transportar imagens que nenhum outro filtro PDF pode representar diretamente. A desvantagem é que um descodificador de referência conforme requer a biblioteca OpenJPEG ou equivalente, que muitos visualizadores de PDF incluem mas que não era universal nos visualizadores mais antigos. Para documentos modernos destinados a visualizadores atuais, isso já não é uma preocupação prática
Incorporar um ficheiro JP2 existente como fluxo JPXDecode tem vantagens precisas. Não há perda de geração: os píxeis que entram são os píxeis que saem quando o visualizador descodifica o PDF. As imagens médicas e de satélite por vezes transportam componentes de profundidade de bit elevada que a recompressão JPEG reduziria para 8 bits por canal; JPXDecode pode preservar esses valores. E o tamanho do ficheiro da incorporação iguala o tamanho do ficheiro JP2 de origem, o que é frequentemente menor do que a alternativa de Flate em imagens fotográficas
A pilha de descodificação no HotPDF
A unidade HPDFJpeg2000 trata do carregamento. Expõe dois tipos: THPDFJpeg2000Decoder, que chama OpenJPEG 2.5.4 para descodificar um fluxo de bytes JP2 em píxeis brutos, e TJpeg2000Bitmap, que transporta o resultado descodificado — dimensões, contagem de componentes, profundidade de bits e os próprios dados de píxeis — numa forma que o resto da biblioteca pode converter para um THPDFImage pronto para colocação
O macro HPDF_REGISTER_JPEG2000_PICTURE liga a unidade ao motor de imagem do HotPDF. Sem ela, as funções de descodificação estão disponíveis mas a chamada de carregamento de nível superior não sabe usá-las. Colocar a diretiva uses num ficheiro da aplicação é a única alteração de configuração necessária
uses
HPDFJpeg2000; // registers the JPEG 2000 decoder with HotPDF
{$I HPDF_REGISTER_JPEG2000_PICTURE} // wire decoder into image-load path
Com o registo feito, chamar LoadImageFromFile num ficheiro .jp2 ou passar bytes JP2 para LoadImageFromStream segue o mesmo caminho que qualquer outra imagem. O codificador de imagem interno verifica a assinatura do ficheiro, invoca THPDFJpeg2000Decoder, recebe um TJpeg2000Bitmap, empacota-o como um XObject JPXDecode e escreve-o na árvore de objetos do PDF. O código de chamada não vê nada deste mecanismo
Carregar e colocar uma imagem JPEG 2000
O fluxo de trabalho de utilização é idêntico a qualquer outra imagem HotPDF depois do registo. Carrega-se a imagem, obtém-se um índice e coloca-se esse índice na página nas coordenadas desejadas
var
Pdf: THotPDF;
ImgIdx: Integer;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.NewDocument;
Pdf.NewPage;
ImgIdx := Pdf.LoadImageFromFile('photo.jp2');
if ImgIdx >= 0 then
Pdf.DrawImage(ImgIdx, 50, 700, 200, 150); // x, y, width, height in points
Pdf.SaveToFile('output.pdf');
finally
Pdf.Free;
end;
end;
A variante de fluxo funciona da mesma forma quando os bytes JP2 chegam de uma base de dados ou de um pedido de rede em vez de um ficheiro em disco. Passe um TStream posicionado no início dos dados JP2 para LoadImageFromStream e o índice resultante comporta-se de forma idêntica
O que o OpenJPEG 2.5.4 traz
O OpenJPEG é a implementação de referência de código aberto do JPEG 2000, mantida pelo grupo JPEG. A versão 2.5.4 inclui correções de segurança contra fluxos JP2 malformados que as versões anteriores tratavam incorretamente. Para uma biblioteca que incorpora ficheiros de fontes externas em PDFs de produção, isso é relevante: um ficheiro JP2 de entrada corrompido ou malicioso deve falhar de forma limpa em vez de desencadear um estouro de memória intermédia
A biblioteca está ligada estaticamente à DLL do HotPDF em Windows. Não são necessárias dependências de tempo de execução separadas no sistema de destino. Para Lazarus / FPC em Linux e macOS, consulte as notas de compilação na documentação do componente: o OpenJPEG pode ser ligado estaticamente ou dinamicamente dependendo do alvo
Espaços de cor e componentes múltiplos
O JPEG 2000 pode codificar imagens com qualquer contagem de componentes. Um ficheiro médico DICOM JP2 pode transportar doze componentes espectrais. O descodificador HotPDF lida com RGB (3 componentes), RGBA (4 componentes com alfa) e escala de cinzentos (1 componente) diretamente. Para contagens de componentes fora dessas, TJpeg2000Bitmap expõe os dados de píxeis brutos e as contagens de componentes para que o código da aplicação os possa remapear antes de entregar ao motor de imagem
O canal alfa merece menção. Quando um ficheiro JP2 inclui um componente alfa, o HotPDF honra-o ao criar uma máscara mole XObject que o visualizador aplica quando renderiza a imagem sobre o fundo da página. Não é necessário trabalho adicional da parte do código chamador: a detecção de componente alfa é automática
Quando recodificar em vez de incorporar diretamente
A incorporação JPXDecode direta é a escolha correta quando o ficheiro JP2 de origem é fiável, os visualizadores alvo suportam PDF 1.5 ou superior e a preservação de qualidade é importante. Há casos em que a recodificação é melhor. Se o PDF tiver de conformar-se com PDF/A-1 (que proíbe JPXDecode), comprimir novamente para Flate ou DCT é obrigatório. Se a imagem de origem for de má qualidade e uma passagem de melhoria de qualidade for desejável, renderizar para píxeis e aplicar a melhoria antes da compressão final faz sentido. O HotPDF suporta ambos os caminhos; o ponto de escolha é o tipo de compressão de imagem que passa antes do carregamento
Para a maioria das aplicações que gerem imagens profissionais, arquivos de documentos ou saída de câmara, a incorporação direta é a escolha certa. Os pontos de referência de qualidade e tamanho favorecem-na, o suporte de visualizadores modernos é universal e o caminho de código é mais simples. O artigo sobre saída de relatório com fontes e imagens abrange as APIs de colocação de imagem utilizadas aqui. Os critérios de conformidade que determinam quando JPXDecode é permitido num arquivo estão detalhados em validação PDF/A, PDF/X e PDF/UA em Delphi. Ambas as funcionalidades fazem parte do Componente HotPDF para Delphi e C++Builder