Página 1 de 2
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 19 Out 2023 17:13
por NiltonGM
Pessoal, estou tentando enviar um binario do arquivo de imagem tipo logotipo (jpeg ou png) para uma API, eu uso o hb_MemoRead() para carregar o arquivo e enviar pela API, porem o logo ao ser carregado para a variável é corrompido ou truncado, tentei usar o MemoRead() que trunca o EOF, mas acontece a mesma coisa, quando envio o imagem pelo Insomnia, vai sem nenhum problema, só pelo harbour que dá pau na imagem.
Obs: Uso o hb_MemoRead() para enviar PDF e Certificado Digital codificado na base64 sem problemas, também consigo ler (GET) da API um PDF e XML que vem de forma binária e uso o hb_MemoWrit() para salvar em arquivo sem nenhum problema. Alguém já passou por algo semelhante com hb_MemoRead()??
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 19 Out 2023 17:36
por JoséQuintas
MemoRead() à primeira vista não é o problema.
Tá passando como ? Texto ? do outro lado considera ByteStream ou texto? texto tem codepage.
Senão, é fazer em base64.
Mas já passaram casos por aqui da imagem ser salva com configuração inválida, e nem todo leitor/visualizador reconhecer direito.
Salvo de tudo no MySQL: EXE, DLL, JPG, PNG, PFX, etc. sem problemas, base64.
Uso hb_MemoRead() ou MemoRead() e hb_MemoWrite()
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 10:53
por NiltonGM
Oi Zeh,
A imagem deve ser passado como arquivo binário, no Insomnia eu consigo passar sem problemas, o arquivo é passado como File binary, o Content-type "image/jpeg", é enviado sem problemas, estou testando o conjunto de funções FOpen() e FRead() conforme sugestão da IA no chatgpt.
Observe que existe uma constante no fileio.ch para ler um arquivo binário:
FD_BINARY:
Código: Selecionar todos
nFileHandle := FOpen(fileLogo, FO_READ + FD_BINARY)
if !(nFileHandle == F_ERROR)
nSize := hb_FSize(fileLogo)
binaryFile := Space(nSize)
nSize := FRead(nFileHandle, @binaryFile, nSize)
FClose(nFileHandle)
if !Empty(binaryFile)
logotipo := TApiLogotipo():new(cnpj)
if logotipo:Enviar(binaryFile, hb_FNameExt(fileLogo))
RegistryWrite(REGISTRY_PATH + "logotipo\LogoFile", fileLogo)
RegistryWrite(REGISTRY_PATH + "logotipo\uploaded", 1)
SetProperty('setup', 'Label_StatusLogotipo', 'value', 'Logotipo carregado com sucesso!')
SetProperty('setup', 'Label_StatusLogotipo', 'FontColor', GREEN_OCRE)
else
SetProperty('setup', 'Label_StatusLogotipo', 'value', 'Erro ao carregar Logotipo!')
SetProperty('setup', 'Label_StatusLogotipo', 'FontColor', RED)
MsgStop(getMessageApiError(logotipo), "Erro ao carregar Logotipo")
endif
else
MsgStop({"Erro ao ler o arquivo de imagem.", hb_eol(), "nSize: ", nSize}, "Erro ao ler Logotipo")
endif
else
MsgStop("Erro ao abrir o arquivo de imagem.", "Erro ao carregar Logotipo")
endif
Vamos ver se dá certo.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 11:01
por alaminojunior
Verifique se não é o tamanho do arquivo.
Não sei atualmente, mas existia problema para armazenar em memória dados muito grandes.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 11:18
por NiltonGM
Tive erro com a função FRead() retornando 0 bytes, fiz a seguinte alteração abaixo:
Código: Selecionar todos
nFileHandle := FOpen(fileLogo)
if !(nFileHandle == F_ERROR)
nSize := hb_FSize(fileLogo)
binaryFile := Space(nSize)
nSize := FRead(nFileHandle, @binaryFile, nSize)
FClose(nFileHandle)
if !Empty(binaryFile)
logotipo := TApiLogotipo():new(cnpj)
if logotipo:Enviar(binaryFile, hb_FNameExt(fileLogo))
RegistryWrite(REGISTRY_PATH + "logotipo\LogoFile", fileLogo)
RegistryWrite(REGISTRY_PATH + "logotipo\uploaded", 1)
SetProperty('setup', 'Label_StatusLogotipo', 'value', 'Logotipo carregado com sucesso!')
SetProperty('setup', 'Label_StatusLogotipo', 'FontColor', GREEN_OCRE)
else
SetProperty('setup', 'Label_StatusLogotipo', 'value', 'Erro ao carregar Logotipo!')
SetProperty('setup', 'Label_StatusLogotipo', 'FontColor', RED)
MsgStop(getMessageApiError(logotipo), "Erro ao carregar Logotipo")
endif
else
MsgStop({"Erro ao ler o arquivo de imagem.", hb_eol(), "Erro: ", }, "Erro ao ler Logotipo")
endif
else
MsgStop({"Erro ao abrir o arquivo de imagem.", "Erro: ", FError()}, "Erro ao carregar Logotipo")
endif
endif
A leitura do arquivo funcionou, mas obtive o mesmo erro que tive com hb_MemoRead(), o envio à API do binário em uma variável está causando algum tipo de erro como truncamento de bytes ou outra coisa que não descobri, pelo Insomnia (igual o Postman), usando as mesmas configurações que uso pra enviar pra API, funciona muito bem, não há corrupção do binário enviado.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 12:25
por alaminojunior
NiltonGM escreveu:Tive erro com a função FRead() retornando 0 bytes, fiz a seguinte alteração abaixo:
Código: Selecionar todos
nFileHandle := FOpen(fileLogo)
if !(nFileHandle == F_ERROR)
nSize := hb_FSize(fileLogo)
binaryFile := Space(nSize)
nSize := FRead(nFileHandle, @binaryFile, nSize)
FClose(nFileHandle)
if !Empty(binaryFile)
logotipo := TApiLogotipo():new(cnpj)
if logotipo:Enviar(binaryFile, hb_FNameExt(fileLogo))
RegistryWrite(REGISTRY_PATH + "logotipo\LogoFile", fileLogo)
RegistryWrite(REGISTRY_PATH + "logotipo\uploaded", 1)
SetProperty('setup', 'Label_StatusLogotipo', 'value', 'Logotipo carregado com sucesso!')
SetProperty('setup', 'Label_StatusLogotipo', 'FontColor', GREEN_OCRE)
else
SetProperty('setup', 'Label_StatusLogotipo', 'value', 'Erro ao carregar Logotipo!')
SetProperty('setup', 'Label_StatusLogotipo', 'FontColor', RED)
MsgStop(getMessageApiError(logotipo), "Erro ao carregar Logotipo")
endif
else
MsgStop({"Erro ao ler o arquivo de imagem.", hb_eol(), "Erro: ", }, "Erro ao ler Logotipo")
endif
else
MsgStop({"Erro ao abrir o arquivo de imagem.", "Erro: ", FError()}, "Erro ao carregar Logotipo")
endif
endif
A leitura do arquivo funcionou, mas obtive o mesmo erro que tive com hb_MemoRead(), o envio à API do binário em uma variável está causando algum tipo de erro como truncamento de bytes ou outra coisa que não descobri, pelo Insomnia (igual o Postman), usando as mesmas configurações que uso pra enviar pra API, funciona muito bem, não há corrupção do binário enviado.
Pode parecer estranho, mas tente salvar o conteúdo dessa leitura com Fread() num arquivo txt e depois confira o resultado. Veja se não está salvando com alguma diferença.
Como já citei em outra resposta, já li sobre falha na leitura de dados grandes.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 12:28
por alaminojunior
Olhando no baú aqui ... vi que na leitura para obter o tamanho do arquivo, não uso fSize, mas fSeek
Código: Selecionar todos
hh3:= fopen('c:\alamino\img\273.jpg')
htam:= fseek(hh3,0,2)
fseek(hh3,0,0)
hh4:= space(htam)
fread( hh3, @hh4, htam )
Vai que cola ...
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 15:39
por NiltonGM
alaminojunior escreveu:o
Tentei do seu jeito, não colou, vejo que o erro está em outro lugar, pois se funciona com certificado digital .pfx, .pdf, .xml, porque só .jpg ou .png que não funciona?
O problema deve estar na forma como envio o logotipo pela função win_oleCreateObject("MSXML2.ServerXMLHTTP.6.0")
Código: Selecionar todos
// Forma resumida
connection := win_oleCreateObject("MSXML2.ServerXMLHTTP.6.0")
connection:Open("PUT", "https://api.sandbox.nuvemfiscal.com.br/empresas/57....000115/logotipo", false)
connection:SetRequestHeader("Authorization", "Bearer " + token)
connection:SetRequestHeader("Content-Type", "image/jpeg") // Request Body Schema, isto muda conforme a extensão da imagem (.png ou .jpg)
connection:Send(body) // a var body contém o binário da imagem
connection:WaitForResponse(5000)
...
O arquivo é recebido na api destino, porem corrompido ou truncado, pois não é possível usar a imagem que chegou no destino, ao fazer o GET e comparar, está diferente q qtde de bytes. Se eu usar o Insomnia, vai que é uma beleza, chega perfeito.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 18:07
por alaminojunior
Então nos resta o seguinte:
Normalmente para transmissão de arquivos de imagem (principalmente) se utiliza codificação base64. O Harbour ou xHarbour tem função própria para isso.
Uma breve observação: para gravar este tipo de informação num MySQL por exemplo, precisa ser codificado pois do contrário resulta erro na operação com o banco.
Provavelmente o Insomnia já identifica e faz essa codificação automaticamente.
Codifique o resultado da leitura e experimente enviar para ver o retorno.
Código: Selecionar todos
hFile := FOpen(cPathFile)
nSize := FSeek(hFile,0,2)
fSeek(hFile,0,0)
cBuff := Space(nSize)
FRead( hFile, @cBuff, nSize )
FClose( hFile )
cBuff := HB_Base64Encode( cBuff, nSize )
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 20 Out 2023 19:39
por JoséQuintas
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 21 Out 2023 12:09
por NiltonGM
Zeh, o problema nesse caso do link que você passou é que o Content-type está errado ("content-type", "multipart/form-data"), pois deveria ser image/jpeg, image/png, image/gif conforme a extensão/tipo do arquivo e também a resposta presupõem que quem está enviando para api é também o dono da api para mudar a api para ficar de acordo com o que ele descreveu, com certeza esse não é o meu caso, estou usando API de terceiros e não tenho como dizer que algo está errado se está funcionando para outras aplicações/clientes.
alaminojunior escreveu:Então nos resta o seguinte:
Normalmente para transmissão de arquivos de imagem (principalmente) se utiliza codificação base64. O Harbour ou xHarbour tem função própria para isso.
Uma breve observação: para gravar este tipo de informação num MySQL por exemplo, precisa ser codificado pois do contrário resulta erro na operação com o banco.
Provavelmente o Insomnia já identifica e faz essa codificação automaticamente.
Codifique o resultado da leitura e experimente enviar para ver o retorno.
Código: Selecionar todos
hFile := FOpen(cPathFile)
nSize := FSeek(hFile,0,2)
fSeek(hFile,0,0)
cBuff := Space(nSize)
FRead( hFile, @cBuff, nSize )
FClose( hFile )
cBuff := HB_Base64Encode( cBuff, nSize )
Alamino, a API só pede encode64 para o certificado, a documentação não fala nada de encodar a imagem do logotipo, mas vou tentar codificar, vai que dá certo. Aviso aqui se deu certo ou não. De qualquer forma, consigo enviar o logo de duas maneiras: diretamente no cadastro na web e pelo Insomnia.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 22 Out 2023 12:46
por NiltonGM
Testei com Encode64, também não funcionou, vou dedistir por enquanto já que não é tão imprecindível que esse módulo funcione, vou terminar a integração agora com a API da MDFe que é mais importante, quanto ao CTe já estou enviando, cancelando, consultando, pegando o PDF e XML na versão CTe 4.00.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 31 Out 2023 16:52
por clodoaldomonteiro
Nilton,
A API q está recebendo as requisições, tem alguma área de testes, para que possamos ver como fazer a coisa e ir testando cada um com seus conhecimentos?
Assim ficaria mais fácil ajudar vc.
Ou até se existir algum portal/site que possamos enviar imagens e ver o resultado nele.
E também não sei se tem como você ver o payload do request, como vemos nos navegadores.
Abraços.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 31 Out 2023 17:07
por clodoaldomonteiro
Nilton,
Um teste q vc pode fazer, é abrir uma imagem com o notepad++ Selecionar tudo e colar noutro arquivo, vai ver que o conteúdo colado é diferente, e o que pode estar acontecendo é isso, na hora de ler, os dados passam para a memória de uma forma diferente.
Abraços.
hb_MemoRead() lendo arquivo de imagem (jpg, png)
Enviado: 31 Out 2023 17:07
por JoséQuintas
NiltonGM escreveu:quanto ao CTe já estou enviando, cancelando, consultando, pegando o PDF e XML na versão CTe 4.00.
Estou com problemas no envio síncrono do CTE 4.00
Pode dizer se há algo de diferente nele?
Os demais serviços funcionaram normalmente.