Converter PDF em Base64

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

chicaomogi70
Usuário Nível 1
Usuário Nível 1
Mensagens: 10
Registrado em: 15 Fev 2022 14:36
Localização: Mogi das Cruzes - SP

Converter PDF em Base64

Mensagem por chicaomogi70 »

Como faço para converter um arquivo PDF em Base64 String ?

Se eu converto o arquivo online pela internet, ele retorna uma string enorme, que deve ser exatamente o binário do arquivo em si, convertido para Base64.

Usando

Código: Selecionar todos

resp := hb_base64encode("fatura.pdf")
ele retorna apenas alguns caracteres.

Não achei nenhum exemplo desse comando.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Converter PDF em Base64

Mensagem por Jairo Maia »

chicaomogi70 escreveu:ele retorna apenas alguns caracteres
A sintaxe da função é: HB_Base64Encode( <cString>, <nBytes> ). O segundo parâmetro é obrigatório para que ela funcione.

Tente assim e veja se funciona:

Código: Selecionar todos

cFile := Path + Nome_Arquivo + .Ext
cFileSave64 := Nome_do_arquivo_Base64.Ext

cStringFile := Hb_MemoRead( cFile )

If Len( cStringFile ) > 0
 cFile64 := HB_Base64Encode( cStringFile, Len( cStringFile ) )
 Hb_MemoWrit( cFileSave64, cFile64 )
Else
 Hb_Alert( "Falha ao carregar o arquivo..." )
EndIf
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
chicaomogi70
Usuário Nível 1
Usuário Nível 1
Mensagens: 10
Registrado em: 15 Fev 2022 14:36
Localização: Mogi das Cruzes - SP

Converter PDF em Base64

Mensagem por chicaomogi70 »

obrigado pelo código, funcionou perfeitamente com PDF pequeno,
mas com PDF de 1 MB de tamanho, parece que o 'Hb_MemoRead' não deu conta não,
vou ter que dividir o tamanho em várias variáveis ?

Alguma sugestão do que pode ser quando tenta arquivo PDF grande ?
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Converter PDF em Base64

Mensagem por Jairo Maia »

chicaomogi70 escreveu:mas com PDF de 1 MB de tamanho, parece que o 'Hb_MemoRead' não deu conta não,
O tamanho que Hb_MemoRead() pode carregar é o tamanho da memória disponível. Se algo está errado, não é o Hb_MemoRead(), ele carrega qualquer arquivo de qualquer formato, desde que tenha memória disponível.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Converter PDF em Base64

Mensagem por sygecom »

Acredito a function HB_BASE64ENCODEFILE lhe ajuda.

http://fivewin.com.br/index.php?/topic/ ... em-base64/
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Avatar do usuário
Mario Mesquita
Usuário Nível 4
Usuário Nível 4
Mensagens: 613
Registrado em: 08 Dez 2009 13:47
Localização: Rio de Janeiro

Converter PDF em Base64

Mensagem por Mario Mesquita »

Bom dia a todos.

Eu uso numa função que está funcioanando normalmente. PDF assinado, pra ser incorporado a um XML:

Código: Selecionar todos

FUNCTION Faz_Base64_P7s(xArq, xSai)
LOCAL xP7s, xConvert := "", xTam := FILESIZE(xArq)

IF ! FILE(xArq)
   MSGSTOP("ARQUIVO ASSINADO " + xArq + " NÃO LOCALIZADO. O PDF DEVE SER ASSINADO DIGITALMENTE DEPOIS DE GERADO.")
   RETURN ""
ENDIF

//HB_Base64EncodeFile( xArq, xSai ) - Não lembro porquê mas essa não deu certo pra mim...

xP7s := MEMOREAD(xArq)

xConvert = HB_Base64Encode( xP7s, xTam )   // converte o conteúdo do arquivo em base64

RETURN xConvert
Saudações,
Mario.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Converter PDF em Base64

Mensagem por JoséQuintas »

Não compliquem.

Seu uso inicial está correto.
O problema é que colocou pra converter o NOME do arquivo, e não o conteúdo.

Como já foi dito, o limite é a memória disponível, mas considere o seguinte:

Código: Selecionar todos

x := MemoRead( "arquivo.pdf" )
x2 := hb_Base64Encode( x )
hb_MemoWrit( x2 )
Nisso acima, está usando o conteúdo 5 vezes, então, se a memória disponível fosse 2GB, só poderia usar arquivo de 400MB, isso se considerar que em base64 teria o mesmo tamanho, mas é sempre maior. Passar por referência faz diferença, mas não vém ao caso agora.
De qualquer forma, até mesmo 100MB seria tranquilo.

Tudo numa linha só talvez economize memória, por usar menos variáveis, mas acho que nem é esse o problema.

Código: Selecionar todos

hb_MemoWrit( "arquivo.base64", hb_base64Encode( MemoRead( "arquivo.pdf" ) ) )
test.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Converter PDF em Base64

Mensagem por JoséQuintas »

test.png
Outro teste, EXE de quase 200MB.

Só que teve uma coisa curiosa NOS DOIS CASOS:
Na primeira execução nada aconteceu.
Na segunda foi normal.

Achei que foi por fazer rápido, mas acontecer nas duas vezes deixa na dúvida se o Windows tem alguma coisa a ver com isso.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Converter PDF em Base64

Mensagem por Jairo Maia »

JoséQuintas escreveu:Não compliquem.
Não foi a intenção José.... Como nunca tentei usar sem o segundo parâmetro (e vou continuar usando sempre informando o segundo parâmetro), então nunca testei se o resultado seria correto sem ele.

Apenas uso como manda o manual:
The number of bytes to encode from <cString> must be passed as second parameter.
Use the expression Len(<cString>) to encode the entire string.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Converter PDF em Base64

Mensagem por JoséQuintas »

Sei disso.
E não fez errado, mostrou igual ao manual.

Não me referi a nenhuma resposta específica, mas ao conjunto de respostas que se formou.
Sei que todos fizeram com boas intenções.
Mas se continuasse sendo usada string errada, nenhuma alternativa funcionaria.

Nota:
Uso assim sempre, o tempo todo, desde a primeira vez.
Salvo binários no MySQL em formato base64, incluindo o próprio EXE.
Minha atualização do EXE é pelo MySQL.
Só já não lembro mais se isso começou no tempo do harbour 3.4 ou do 3.2, então não sei se pode haver diferença entre eles ou até entre XHarbour.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Converter PDF em Base64

Mensagem por JoséQuintas »

Apenas pra informação, encontrei isto no changelog do harbour 3.2, que vém na distribuição
2014-01-22 02:44 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
; modifications taken from Viktor's branch.

* include/hb.ch
+ added hbserial.ch

* src/rtl/base64c.c
+ HB_BASE64ENCODE(): added second parameter to request
specific line length for the output. Line length
should be specified in visible characters (w/o the
2 EOL bytes). EOL is fixed to CRLF.
https://en.wikipedia.org/wiki/Base64
; probably there exist more optimal implementations
; (code slightly modified)
Procurei nos commits, e não tem mudança depois disso, a não ser ajustes no texto de anotações.
Como a compatibilidade é mantida, o parâmetro é opcional, mas se colocar menor que o tamanho, vai dividir o resultado em linhas.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Mario Mesquita
Usuário Nível 4
Usuário Nível 4
Mensagens: 613
Registrado em: 08 Dez 2009 13:47
Localização: Rio de Janeiro

Converter PDF em Base64

Mensagem por Mario Mesquita »

Pessoal, bom dia.

Estou com um aparente problema no HB_Base64Encode. Estou fazendo uns testes para me inteirar sobre APIs e num teste de
uma rotina cedida por um amigo, estava dando erro de autenticação na URL que estou testando.

Estou compilando com a HMG 3.5 ANSI. Só que, por curiosidade, compilei com a versão 3.0.46 que ainda uso e deu response correto.

Investigando, notei que a função gerava um string com 64 posições enquanto a gerada com a 3.5 gera com 68 poisções. Vendo mais fundo,
notei que entrou no fim CHR(10) ou CHR(13) que deve ter causado a recusa da autenticação.

Será que tem a ver com essa alteração que o Quintas reportou aí em cima?

A função:

Código: Selecionar todos

Function Teste_02()
mtj_url             := "" // 'endereço da API'
mtj_username   := 'username'                              // 'usuário' - len=14
mtj_password   := 'senha!' // 'senha'   - len=32
mtj_ultimadata := CTOD('25/07/2023')
loXMLHTTP      := CREATEOBJECT("MSXML2.XMLHTTP")  
xString        := mtj_username + ':' + mtj_password
xUrl           := mtj_url + dtos(mtj_ultimadata)
xAuth          := HB_Base64Encode( xString, LEN(xString) )

WITH OBJECT loXMLHTTP //AS MSXML2.XMLHTTP
	:OPEN("GET", xUrl, .f.)
	:setRequestHeader("Content-Type","application/json")
	:setRequestHeader("Authorization","Basic " + xAuth ) 
 	:send()
	mresposta = :responsetext
endwith
MsgInfo('Resposta:' + chr(13) + mresposta)

Return Nil
A versão 3.5 já deve ter essa atualização do 3.2 não? Senão, como resolve isso?
Atenção! Msg Editada por Itamar Lins Jr. para remove login e senha.
Saudações,
Mario.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Converter PDF em Base64

Mensagem por JoséQuintas »

Atenção na alteração:

O parâmetro NÃO existia, o retorno era normal.
O parâmetro é OPCIONAL, é pra dividir em blocos adicionando mudança de linha.
Na dúvida, acho que é melhor usar SEM o parâmetro de tamanho.
Mesmo assim, seriam 2 bytes e não 4.
Compare as duas strings pra ver o que muda entre elas.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Mario Mesquita
Usuário Nível 4
Usuário Nível 4
Mensagens: 613
Registrado em: 08 Dez 2009 13:47
Localização: Rio de Janeiro

Converter PDF em Base64

Mensagem por Mario Mesquita »

Boa noite, pessoal.

Isso aí, Quintas. Sem o segundo parâmetro fez corretamente. Pra falar a verdade, até então não sabia que ele era opcional. Na consulta que tenho não cita isso,
talvez por isso sempre achei que era obrigatório.

Valeu, Itamar. Só tinha deixado os dados pra ilustrar a questão e só tirei a URL. Obrigado.

Saudações,
Mario.
Avatar do usuário
Mario Mesquita
Usuário Nível 4
Usuário Nível 4
Mensagens: 613
Registrado em: 08 Dez 2009 13:47
Localização: Rio de Janeiro

Converter PDF em Base64

Mensagem por Mario Mesquita »

Bom dia a todos.

Ainda fazendo os testes com API, tentei editar as strigs convertidas pelo Encode 64 pra entender a diferença, mas sem o segundo parâmetro, dá erro de compilação. Como uso HMG, faço o display delas com MsgInfo().

Não entendi nada, se volta um string, pq sem o tamanho da string dá isso?

Se alguém souber, agradeço.

Saudações,
Mario.
Responder