No artigo de hoje, vamos mostrar como transformar um PDF com o padrão de cores RGB em CMYK usando AdvPL com GhostScript.
O GhostScript é um projeto conhecido no mundo da programação, que tem uma parte Open Source. Com ele nós conseguimos manipular arquivos PDF.
Um dos recursos interessantes, é o fato de conseguir mudar o padrão de cores de um arquivo PDF. Supondo então, que você tenha essa necessidade, nós conseguimos através de uma integração com o GhostScript.
Então antes de mais nada, baixe o GhostScript disponível nesse link – https://www.ghostscript.com/releases/gsdnld.html
Depois de fazer a instalação, baixe o código fonte abaixo, e se atente ao caminho na variável cPastaGS, que é ela que define a pasta onde tem os executáveis do GhostScript.
Antes de vermos o funcionamento do código, apenas para contextualizar, quando geramos um PDF nativo em AdvPL através da FWMSPrinter, ele usa o printer.exe para renderizar, que por sua vez é baseado no Haru Free PDF.
Esse arquivo é gerado então com um padrão de cores usando RGB (Red, Green e Blue), mas caso o usuário precise mandar o arquivo para a gráfica ou tratar o arquivo no Corel Draw, ai é necessário usar o padrão CMYK (Cyan, Magenta, Yellow e Black), ideal por exemplo, para um catálogo de produtos ou folder.
Então via AdvPL, nós geramos o relatório em PDF RGB usando FWMSPrinter, e depois já acionamos a customização para transformar em CMYK.
Abaixo um exemplo de como utilizar:
//Define a pasta e o arquivo cPastaRel := GetTempPath() cArquivo := "relatorio_" + dToS(Date()) + "_" + StrTran(Time(), ':', '-') + ".pdf" //Cria o PDF oPrint := FWMSPrinter():New(cArquivo, IMP_PDF, .F., , .T., , @oPrint, , , , ,.T.) oPrint:cPathPDF := cPastaRel oPrint:lViewPDF := .F. // ... Faz as impressões ... //Gera o PDF via FWMSPrinter oPrint:Print() //Aciona a transformação de RGB para CMYK u_zCMYK(cPastaRel, cArquivo, .T.)
E abaixo segue a função completa que aciona o GhostScript:
//Bibliotecas
#Include "TOTVS.ch"
/*/{Protheus.doc} User Function zCMYK
Faz a conversão de um PDF em RGB para CMYK
@type Function
@author Atilio
@since 22/02/2023
@param cPastaPDF, Caractere, Pasta onde esta o PDF original
@param cArquiRGB, Caractere, Nome do arquivo PDF Original com cores em RGB
@param lAbrirPDF, Lógico, Define se irá abrir o PDF CMYK após a conversão
@return aDados, Array, Retorna um array sendo posição [1] se deu certo ou não e [2] nome do arquivo PDF CMYK
@example
u_zCMYK("C:\spool\tst", "ptfatm29_original.pdf", "C:\Program Files\gs\gs9.55.0\bin", .T.)
/*/
User Function zCMYK(cPastaPDF, cArquiRGB, lAbrirPDF)
Local aArea := FWGetArea()
Local lDeuCerto := .F.
Local cComando := ""
Local cArquiCMYK := ""
Local aRetorno := {}
Local cPastaGS := SuperGetMV("MV_X_GHOST", .F., "C:\Program Files\gs\gs9.55.0\bin\")
Default cPastaPDF := ""
Default cArquiRGB := ""
Default lAbrirPDF := .F.
//Retira os espaços vazios
cPastaPDF := Alltrim(cPastaPDF)
cArquiRGB := Alltrim(cArquiRGB)
cPastaGS := Alltrim(cPastaGS)
//Adiciona \ caso esteja faltando
cPastaPDF := cPastaPDF + Iif(Right(cPastaPDF, 1) != "\", "\", "")
cPastaGS := cPastaGS + Iif(Right(cPastaGS, 1) != "\", "\", "")
//Somente os conteúdos da conversão e eles são válidos (existentes)
If ! Empty(cPastaPDF) .And. ! Empty(cArquiRGB) .And. ExistDir(cPastaGS) .And. File(cPastaPDF + cArquiRGB)
//O nome do arquivo CMYK, será igual o original, com "_cmyk" antes da extensão
cArquiCMYK := cArquiRGB
cArquiCMYK := SubStr(cArquiCMYK, 1, At(".", cArquiCMYK)-1)
cArquiCMYK := cArquiCMYK + "_cmyk.pdf"
//Monta o comando para converter o PDF
cComando := ' -dSAFER -dBATCH -dNOPAUSE -dNOCACHE '
cComando += ' -sDEVICE=pdfwrite -sColorConversionStrategy=CMYK -dProcessColorModel=/DeviceCMYK '
cComando += ' -sOutputFile="' + cPastaPDF + cArquiCMYK + '" '
cComando += ' "' + cPastaPDF + cArquiRGB + '"'
ShellExecute("OPEN", "gswin64.exe", cComando, cPastaGS, 1)
//Se o arquivo CMYK existe, deu certo a conversão
If File(cPastaPDF + cArquiCMYK)
lDeuCerto := .T.
//Se for para abrir o PDF
If lAbrirPDF
ShellExecute("OPEN", cArquiCMYK, "", cPastaPDF, 1)
EndIf
EndIf
EndIf
//Define o retorno
aRetorno := {lDeuCerto, cArquiCMYK}
FWRestArea(aArea)
Return aRetorno
Referências:
Bom pessoal, por hoje é só.
Abraços e até a próxima.