hb_MemoRead() lendo arquivo de imagem (jpg, png)

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

Moderador: Moderadores

Avatar do usuário
NiltonGM
Usuário Nível 3
Usuário Nível 3
Mensagens: 397
Registrado em: 05 Jun 2014 23:47
Localização: Caieiras/SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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()??
Nilton Medeiros
nilton@sistrom.com.br
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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()
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
NiltonGM
Usuário Nível 3
Usuário Nível 3
Mensagens: 397
Registrado em: 05 Jun 2014 23:47
Localização: Caieiras/SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
Nilton Medeiros
nilton@sistrom.com.br
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
NiltonGM
Usuário Nível 3
Usuário Nível 3
Mensagens: 397
Registrado em: 05 Jun 2014 23:47
Localização: Caieiras/SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
Nilton Medeiros
nilton@sistrom.com.br
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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 ...
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
NiltonGM
Usuário Nível 3
Usuário Nível 3
Mensagens: 397
Registrado em: 05 Jun 2014 23:47
Localização: Caieiras/SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
Nilton Medeiros
nilton@sistrom.com.br
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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 )
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem por JoséQuintas »

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
NiltonGM
Usuário Nível 3
Usuário Nível 3
Mensagens: 397
Registrado em: 05 Jun 2014 23:47
Localização: Caieiras/SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
Nilton Medeiros
nilton@sistrom.com.br
Avatar do usuário
NiltonGM
Usuário Nível 3
Usuário Nível 3
Mensagens: 397
Registrado em: 05 Jun 2014 23:47
Localização: Caieiras/SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
Nilton Medeiros
nilton@sistrom.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

hb_MemoRead() lendo arquivo de imagem (jpg, png)

Mensagem 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.
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/
Responder