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.