Como gerar um PDF com padrão CMYK ao invés de RGB via AdvPL

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.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

Deixe uma resposta

Terminal de Informação