WX - Trabalhando com Byte Array
Débuté par Boller, 04 juin 2016 01:21 - 28 réponses
Membre enregistré 3 860 messages
Posté le 04 juin 2016 - 01:21
Prezados, Estarei passando um exemplo aqui para ler um arquivo pdf em uma matriz de bytes. A linguagem WL, permite fazer a leitura de um arquivo pdf.s Auxis string s DocumentTitleis string MyBufferis Buffers DocumentTitle= fExtractPath ( s Aux, fFileName ) MyBuffer= fLoadText ( s Aux ) fSaveText ( "TEST.PDF" , myBuffer )
LEITURA DE BYTE ARRAY MyBuffer is Buffer = fLoadBuffer ( "TEST.PDF" ) slice is Buffer = MyBuffer [ [ 1 TO 8 ] ] n is int = Length ( MyBuffer) fileArr is array of n byte FOR i = 1 TO n fileArr[ i ] = MyBuffer[ [ i ] ] END
Como pode ser visto no código, eu salvo na variável buffer para um arquivo com extensão pdf e depois que eu posso ler esse arquivo sem erros em qualquer leitor de PDF. Posso entao usar o comando Crypt para serializar o buffer em uma grande string de caracteres, letras e números e enviar via webservice. E com UnCrypt no outro lado remonto o buffer para ter o arquivo pdf e assim conseguimos fazer algo muito parecido com o Teletransporte do filme Star Trek. kkkk... Crypt:http://help.windev.com/en-US/… buf Base64 isbuffer = Crypt ( buf ToEncode, "" , compressNone + cryptNone , encodeBASE64 )
Uncrypt:http://help.windev.com/en-US/… StringToEncrypt is string = "The number of my account in Switzerland is 74538290" Password is string = "JamesBond007" EncryptedString is string DecryptedString is string EncryptedString = Crypt ( StringToEncrypt, Password, cryptSecure ) ... DecryptedString = Uncrypt ( EncryptedString, Password, cryptSecure ) Info ( "The encrypted message meant: " + DecryptedString)
Assim eu posso usando os comandos acima enviar o buffer (byte array) com o formato de um bloco de texto para um webservice. E ainda posso fazer com que o webservice responda de volta: Arquivo PDF inválido ou válido. Espero que o exemplo ajude a comunidade a produzir novos exemplos e novas soluções. Forte abraço -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 9949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 24 mars 2020 - 23:33
Prezados Esse assunto é muito solicitado e vou passar umas orientações adicionais No lado do servidor na tabela de cadastro de produtos pense em ter os seguintes campos: IdProduto NomeProduto ImagemGrande binário ImagemThumbs binário ImagemGrandeZipada binário ImagemThumsZipada binário Ao gravar uma imagem de um produto Salvar a imagem com 80% no campo ImagemGrande Salvar essa mesma imagem redimensionando para um tamanho menor para ImagemThumbs Zipar o buffer e salvar o binário ImagemGrandeZipada Zipar o buffer e salvar o binário ImagemThumsZipada Quando o Webservice requisitar o produto tem as duas imagens zipadas e salvas em 80% é reduzida para Thumbs A requisição não terá o tempo de processamento de zipar para entregar ao celular que requisitou a informação Ao chegar no celular pelo Webservice faz a descompactacao e salvamento da informação na tabela Hfsql Classic as duas imagens Esse procedimento agiliza o download e garante a exibição dos dados mesmo em off-line. Espero ter ajudado com essa sugestão Um forte abraço a todos -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 10 avril 2020 - 14:26
Ou use Bufimage is buffer = dliadbuffer( « imagem.jpg ») ImagemString is string = encode(bufimagem, base64) Reverso ImagemBuff us buffer = decode(bufimagem, base64) -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 27 avril 2020 - 20:56
Boa tarde... Nossos clientes as vezes mandam protocolos impressos e gostaria de digitalizar e gravar no HFSQL. Qual seria o melhor método? Gravar a imagem dentro do banco ou criar um link das imagem em uma pasta? Alguém tem exemplo disso ? Tudo depende do teu gosto as duas funcionam (base binária ou link ftp httprequest) O campo binário do Hfsql é muito bom Como eu faço: - Crio uma tabela t001_pessoas E nela crio os campos Mas não coloco o binário nessa tabela da foto Crio outra tabela t002_pessoas_fotos Relaciono e coloco o campo binário Isso não vai deixar lento vai funcionar ok e o tamanho do buffer da imagem vai para essa tabela Funciona muito bem não diminui velocidade de consulta Só vai transitar na rede a foto somente quando pedir ela Se der um select * não terei o buffer da foto transitando na rede sem motivo Eu acho que é o mais lógico Se for com link terá que fazer um http request além de um select Será mais complexo, mas vai funcionar Serão 4 operações e com a tabela binária, reservar o link numa variável e consultar com httprequest e depois um httpgettesult. E um select com inner join 2 operação tem o resultado em um buffer ou em um array de string encode64 que terá que converter para buffer Guardar no banco terá um consumo a mais de espaço, mas é bem simples e garantido Se for link se for ip e trocou para DNS ou para outro ip ou DNS daí o link ficou inútil, não vai baixar OK -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 28 avril 2020 - 04:46
Membre enregistré 3 860 messages
Posté le 08 mars 2021 - 16:56
Procedure WSObterListaMensagens( ) NextTitle ( "" ) HourGlass ( ) url is string = "" + gs UrlBackend + "/WSListarMensagens.rule?sys=EDU&alunoID=" + gloAluno_id_externo+ "" IF httpRequest ( url) = True gv RetornoMsg = JSONToVariant ( HTTPGetResult ( ) ) IF gv RetornoMsg.status = "OK" THEN x is int v Total is int = gv RetornoMsg.mensagens .. Count LOOP ( v Total) x+ + HReset ( tab _mensagens) IF HReadSeek ( tab _mensagens, msg_chave_externa, gv RetornoMsg.mensagens [x] . chave_externa , hIdentical ) = False THEN buf FotoMsg1 is Buffer = Decode ( gv RetornoMsg.mensagens [x] . img_mensagem , encodeBASE64 ) imageFoto is Image = buf FotoMsg1 dSaveImageJPEG ( imageFoto, fCurrentDir ( ) + "\imagemfoto.jpg" , 80 ) buf FotoMsg2 is Buffer = fLoadBuffer ( fCurrentDir ( ) + "\imagemfoto.jpg" ) HReset ( tab _mensagens) HReadSeek ( tab _mensagens, msg_chave_externa, gv RetornoMsg.mensagens [x] . chave_externa , hIdentical ) tab _mensagens.msg_chave_externa = gv RetornoMsg.mensagens [x] . chave_externa tab _mensagens.alu_chave_externa = gv RetornoMsg.mensagens [x] . id_aluno tab _mensagens.alu_instituicao_id = gv RetornoMsg.mensagens [x] . id_instituicao tab _mensagens.msg_nome_remetente = gv RetornoMsg.mensagens [x] . nome_remetente tab _mensagens.msg_assunto = gv RetornoMsg.mensagens [x] . assunto tab _mensagens.msg_conteudo = gv RetornoMsg.mensagens [x] . conteudo tab _mensagens.msg_fotografia_msg = buf FotoMsg2 tab _mensagens.msg_resposta_sim = gv RetornoMsg.mensagens [x] . resposta_sim tab _mensagens.msg_resposta_nao = gv RetornoMsg.mensagens [x] . resposta_nao tab _mensagens.msg_resposta_talvez = gv RetornoMsg.mensagens [x] . resposta_talvez tab _mensagens.msg_dh_cadastro = gv RetornoMsg.mensagens [x] . dh_cadastro IF HAdd ( tab _mensagens) = True THEN ELSE Error ( ErrorInfo ( ) , HErrorInfo ( ) ) END END END ELSE ToastDisplay ( gFontBold ( ) + gFont ( "Arial" ) + gFontSize ( 8 ) + ... gPen ( RGB ( 255 , 255 , 255 ) ) + gv RetornoMsg.Erro , ... toastShort , vaBottom , haCenter ) END ELSE ToastDisplay ( gFontBold ( ) + gFont ( "Arial" ) + gFontSize ( 6 ) + ... gPen ( RGB ( 255 , 255 , 255 ) ) + "Ops! Sem resposta do servidor!" , ... toastShort , vaBottom , haCenter ) END Multitask ( - 1 ) HourGlass ( False ) NextTitle ( "" )
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 09 mars 2021 - 14:56
Procedure RedimencionarFoto( ImgOriginal) buf Foto is Buffer Foto is Image = ImgOriginalIF Length ( ImgOriginal) > 0 dSaveImageJPEG ( Foto, fCurrentDir ( ) + "\imagemfoto.jpg" , IMG_ PADRAO_AJUSTADA ) buf Foto = fLoadBuffer ( fCurrentDir ( ) + "\imagemfoto.jpg" ) ELSE fDelete ( fCurrentDir ( ) + "\imagemfoto.jpg" , frReadOnly ) END RETURN ( buf Foto)
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 09 mars 2021 - 15:12
Prezados, Caso nao tenha foto, coloca uma foto na posicao negativa e atribui ela e descobre pelo tamanho do buffer se tem ou nao a foto num campo binario usando LENGTH > 0Procedure MyWindow ( gMensagem_id) QRY_MENSAGEM_SELECIONADA_ID.Parammsg_id = gMensagem_idIF HExecuteQuery ( QRY_MENSAGEM_SELECIONADA_ID) = True THEN FOR E ACH QRY_MENSAGEM_SELECIONADA_ID IF Length ( QRY_MENSAGEM_SELECIONADA_ID.msg_fotografia_msg) > 0 THEN IMG_ foto_mensagem = QRY_MENSAGEM_SELECIONADA_ID.msg_fotografia_msg ELSE IMG_ foto_mensagem = IMG_ sem_foto END END END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 09 mars 2021 - 15:16
Lembre- se 1 - passar parametros a query para filtrar 2 - HExecuteQuery OU HExecuteSQLQuery dispara o camando IF True = para saber se deu certo o comando exemplo IF HExecuteQuery ( Qry_query) = True ELSE END 3 - para ler o retorno tem que fazer um for each na query IF HExecuteQuery ( Qry_query) = True for each Qry_query retorno = Qry_query.campo END ELSE Info ( "Erro" ) END 4 - para atualizar o looper OU table só depois disso tudoTableDisplay ( table_grid, tatinit) se for looperLooperDisplay ( loop_grid, tatinit)
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 16 mars 2021 - 22:57
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 16 mars 2021 - 23:00
Passos: 1 - criar var tipo imagem 2 - ler a imagem que esta no banco com dloadbuffer e armazenar na imagem de memoria 3 - dresize dimensionar o tamanho 800x600 4 - fsavebuffer salvar o que resultou no dresize em disco 5 - dsaveimagejpg salvar em 80% 6 - ler novamente o arquivo e converter ele de volta para imagem de memoria e buffer -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 26 juillet 2021 - 21:47
Fica do RoneiSELECT a320.numero_foto, a320.descricao_foto, Encode ( a320.foto, ' base64' ) AS foto FROM cad_mercad_ficha_tecnica_fotos a320 WHERE a320.codigo_mercadoria= 1
s SQLSentenca is string dsQRYSelect is Data Source b RetornoSQL is boolean n Registro is int = 0 n CodigoMercadoria is int = ExtractString ( ParParametros, 1 , [ "|" ] ) s SQLSentenca = "SELECT a320.numero_foto,a320.descricao_foto,encode(a320.foto,'base64') AS foto FROM cad_mercad_ficha_tecnica_fotos a320 WHERE a320.codigo_mercadoria=" + n CodigoMercadoriab RetornoSQL = SQLExec ( s SQLSentenca, dsQRYSelect) IF b RetornoSQL = False THEN SQLInfo ( dsQRYSelect) gs XML + = "<Error>Erro Select BD - " + SQL.Error + " - " + SQL.MesError + "</Error>" ELSE gs XML + = "<Dados>" WHILE SQLFetch ( dsQRYSelect) = 0 n Registro+ + gs XML + = "<Registro" + n Registro + ">" Preenche_TAG( "NumeroFoto" , SQLGetCol ( dsQRYSelect, 1 ) ) Preenche_TAG( "DescricaoFoto" , SQLGetCol ( dsQRYSelect, 2 ) ) Preenche_TAG( "ImagemFoto" , SQLGetCol ( dsQRYSelect, 3 ) ) gs XML + = "</Registro" + n Registro + ">" END gs XML + = "</Dados>" gs XML + = "<TotalRegistros>" + n Registro + "</TotalRegistros>" END SQLClose ( dsQRYSelect)
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 22 septembre 2021 - 23:16
O Sr Leomar fez vários testes com os mesmos arquivos e tamanhos. RESTSend + / - 20 % mais rápido que HTTPSend
Para guardarmyimage is Buffer = fLoadBuffer ( IMG_ BANNER ) buf Base64 is Buffer = Encrypt ( myimage, "senha" , cryptSecure , encodeBASE64 )
Para AbrirIMG_ NoName1 = Decrypt ( test.image, "senha" , cryptSecure , encodeBASE64 )
By Diego de Ponta Pora -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 17 mars 2022 - 17:22
Saber o tamanho de uma imagem ou se existe imagem no controleimgx is Image = dLoadImage( IMG_NoName1) IF imgx. . BitPerPixel > 0 THEN Info("tem imagem") ELSE Info("vazio") END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 31 mars 2022 - 05:43
BAIXANDO DADOS DE PRODUTOS DE UM WEBSERVICE SOAP E FAZENDO DOWNLOAD DAS IMAGENS DE UMA URL/ / EXECUTANDO O WEBSERVICE E PEGANDO O BLOCO CSV E CHAMANDO A PROC QUE VAI INTERPRETAR O CSV Resultado is string = ws_sel_prodsite_app( ) InterpretaPlotaResulta( Resultado) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PROCEDURE InterpretaBlocoCsv( Resultado) HourGlass( True ) L is int = 0 X is int = 1 Linha is string QtdLinhas is int = StringCount( Resultado, "§" , IgnoreCase) HDeleteAll( view_prodsiteapp) LOOP( QtdLinhas) L+ + Linha = ExtractString( Resultado,L, "§" , FromBeginning) TestaCODWEB is string = NoSpace( ExtractString( Linha, 2 , ";" , FromBeginning) ) HReset( view_prodsiteapp) / / a1 excel poneiro IF HReadSeek( view_prodsiteapp, CODWEB, TestaCODWEB, hIdentical) = False / / nao achou view_prodsiteapp.NOMEWEB = ExtractString( Linha, 1 , ";" , FromBeginning) view_prodsiteapp.CODWEB = ExtractString( Linha, 2 , ";" , FromBeginning) view_prodsiteapp.NOMMARC = ExtractString( Linha, 3 , ";" , FromBeginning) view_prodsiteapp.REFERENCIA = ExtractString( Linha, 4 , ";" , FromBeginning) view_prodsiteapp.PRECO_A = ExtractString( Linha, 5 , ";" , FromBeginning) view_prodsiteapp.PRECO_B = ExtractString( Linha, 6 , ";" , FromBeginning) view_prodsiteapp.DESCUENTO = ExtractString( Linha, 7 , ";" , FromBeginning) view_prodsiteapp.STOCK = ExtractString( Linha, 8 , ";" , FromBeginning) view_prodsiteapp.FOTOS_PATH = "https://www.fastrax.com.py/documentos/" + NoSpace( view_prodsiteapp.CODWEB) + ".png" IF HAdd( view_prodsiteapp) = True Thread_BuscaGravaFoto( view_prodsiteapp.CODWEB, view_prodsiteapp.FOTOS_PATH ) LooperAdd( LOOP_Compra_Rapida, view_prodsiteapp.CODWEB + TAB+ view_prodsiteapp.NOMEWEB + TAB+ view_prodsiteapp.NOMMARC + TAB+ view_prodsiteapp.REFERENCIA + TAB+ view_prodsiteapp.PRECO_A + TAB+ view_prodsiteapp.PRECO_B + TAB+ view_prodsiteapp.DESCUENTO + TAB+ view_prodsiteapp.STOCK) END END END LooperDisplay( LOOP_Compra_Rapida, taInit) / / refresh HourGlass( False ) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PROCEDURE Thread_BuscaGravaFoto( codwebx, pathfoto) NaoExiste is boolean = False HReset( view_prodsiteapp_fotos) IF HReadSeek( view_prodsiteapp_fotos, CODWEB, codwebx, hIdentical) = False THEN NaoExiste = True END IF HNbRec( view_prodsiteapp) > 0 and NaoExiste = True HTTPRequest(pathfoto) //download imagemProduto is Image = HTTPGetResult() view_prodsiteapp_fotos.CODWEB = codwebx view_prodsiteapp_fotos.FOTOBIN = imagemProduto view_prodsiteapp_fotos.FOTOTHUMB = dResize(imagemProduto,60,30,drStretched) IF imagemProduto..BitPerPixel > 0 THEN //Info("tem imagem") HAdd(view_prodsiteapp_fotos) ELSE //Info("vazio") END END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 26 avril 2022 - 21:30
bufImagem is Buffer dSaveImageJPEG(IMG_resultado, fCurrentDir() + fSep() + "Image.JPEG") bufImagem = fLoadBuffer(fCurrentDir() + fSep() + "Image.JPEG") ImagemB64 is Variant = Encode(bufImagem, encodeBASE64) enviar_foto_recortada(id_pessoa,ImagemB64) Close() -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 05 mai 2022 - 18:01
ProcedureSelecionaImagem(Janela,ControleImagem) bufImagebufferisBuffer sFileis string=fSelect("c:\","Selecione uma Foto...","Todos os arquivos (*.*)"+TAB+"*.*"+CR+"PNG"+TAB+"*.PNG"+CR+"JPEG"+TAB+"*.JPEG"+CR+"JPG"+TAB+"*.JPG","*.*") IFfFileExist(sFile) =True bufImagebuffer=fLoadBuffer(sFile) sControlTelaImgis string=Janela+"."+ControleImagem {sControlTelaImg,indControl} =bufImagebuffer dResize({sControlTelaImg,indControl},{sControlTelaImg,indControl}..Width,{sControlTelaImg,indControl}..Height,drHomotheticCentered) bufImagebuffer= {sControlTelaImg,indControl} ELSE Info("Nenhum arquivo selecionado!") END RESULTbufImagebuffer CASE ERROR: -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 05 mai 2022 - 18:02
ProcedureSaveJpg(Imagemis Image) ratioXis real=130/Imagem..Width ratioYis real=130/Imagem..Height IFratioY<ratioXTHEN dResize(Imagem,130,RoundUp(Imagem..Height*ratioX)) ELSE dResize(Imagem,RoundUp(Imagem..Width*ratioY),130) END dSaveImageJPEG(Imagem,"foto.jpg",100) RESULT(Imagem) -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 03 juin 2022 - 20:34
Comando para setar resolução da câmera em 1080x1080 (Para fotos quadradas) Testando em WX26 VideoParameter(vipPhotoResolution, "1080 1080") Rotina para enviar imagem para WS Rest (desenvolvido em PHP) req is httpRequest sURL = URLEncode(sURL) req.URL = sURL req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.42000)" req.Method = httpPost imagem is Variant imagem = Encode(dLoadImage(IMG_FotoPac,imgDefault),encodeBASE64) req.Content = imagem HTTPTimeOut(60s) cMyResponse is httpResponse = HTTPSend(req) IF ErrorOccurred THEN sRetorno = ErrorInfo(errFullDetails) Error(ErrorInfo(errFullDetails)) ELSE sRetorno = cMyResponse..Content ToastDisplay(sRetorno) Close() END -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 08 juin 2022 - 20:25
Prezados, Send Imagem by HTTPCreateForm sem serializar e sem fazer uso de encode base 64 Retificando o exemplo de imagem ficou assim usando HTTPCreateForm muito mais simples: lIdForm is string = "form-data" HTTPTimeOut(60s) HTTPCreateForm(lIdForm) HTTPAddFile(lIdForm, "file", gsLastCapturePath) IF HTTPSendForm(lIdForm, sURL, httpPost, "AGENT") THEN sRetorno is JSON = HTTPGetResult() END Retorna isso aqui: { "eyes": { "ratio":1.060935286195, "response":"olho esquerdo > olho direito por 0.06%" }, "eyebrows": { "ratio":1.060935286195, "response":"olho esquerdo > olho direito por 0.06%", "muscles": [ ], "points": [ ] }, "left_eyebrow": [ ], "right_eyebrow": { "muscles": [ [ "Pr\u00f3cero", 8, 5 ], [ "Corrugador (e)", 336, 5 ], [ "Corrugador (e)", 468, 5 ] ], "points": [ [ 8, 5 ], [ 336, 5 ], [ 468, 5 ] ] }, "horizontal_proportion": [ "61", "89", "100", "84", "54" ], "vertical_proportion": { "muscles": [ ], "firstThird": [ 376.2605480249, 1 ], "secondThird": [ 476.3402145526, 1.265985012388 ], "thirdThird": [ 654.4043092768, 1.739231797519 ] }, "mouth": { "ratio":0.006996088402819, "response":"boca esquerdo < boca direito por 0.01%" }, "width_height": { "ratio":0.9830342433159 }, "nose_width": { "ratio":0.8700248030915 }, "lips_proportion": [ 59.07622195097, 95.08417323614, 1.609516825823 ], "mouth_width_proportion": [ 390.1550973651, 888.6894845783, 401.280450558, 319.189598828 ], "thirds_middle_horizontal_proportion": [ 978.8176541113, 1046.883470115, 1033.853471242 ], "id":"uO3y04xfERN7lHludC8Q", "images":"I9Yd6tuAs0C9iC0IA7RK.jpg,horizontal_proportion_0.png,nose_0.png,thirds_middle_0.png,annotated_image0.png,left_eyebrow_0.jpg,nose_symmetry_0.png,eyebrows_0.jpg,lips_proportion_0.png,proportion_0.png, eyes_0.png,mouth_proportion_0.png" } MUITO OBRIGADO AO FABIANO QUE PASSOU GENTILMENTE ESSE EXEMPLO PARA A COMUNIDADE! -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 23 mars 2023 - 20:00
//SALVANDO IMAGEM NO BANCO DE DADOSpath_imagem is string = fCurrentDir( ) + fSep( ) + "imagem.jpg" dSaveImageJPEG( IMG_foto, path_imagem, 100 ) / / / 100 % DA QUALIDADE 5000 KB + - IF fFileExist( path_imagem) = True THEN Info( "A Imagem " + path_imagem+ " Existe no disco" ) ELSE Info( "A Imagem " + path_imagem+ " nao existe no disco" ) RETURN END T001_FOTOS.T001_DATA_HORA = DateSys( ) + TimeSys( ) T001_FOTOS.T001_FOTO = fLoadBuffer( path_imagem) IF HAdd( T001_FOTOS) = True THEN Info( "GRAVOU FOTO NO BANCO" ) ELSE Error( ErrorInfo( ) ) END
path_imagem is string = fCurrentDir( ) + fSep( ) + "imagem.jpg" dSaveImageJPEG( IMG_foto, path_imagem, 80 ) / / / 80 % DIMINUI DE 5000 KB PARA 500 KB MAS NAO PERDE QUALIDADE A OLHO NU. IF fFileExist( path_imagem) = True THEN Info( "A Imagem " + path_imagem+ " Existe no disco" ) ELSE Info( "A Imagem " + path_imagem+ " nao existe no disco" ) RETURN END T001_FOTOS.T001_DATA_HORA = DateSys( ) + TimeSys( ) T001_FOTOS.T001_FOTO = fLoadBuffer( path_imagem) IF HAdd( T001_FOTOS) = True THEN Info( "GRAVOU FOTO NO BANCO" ) ELSE Error( ErrorInfo( ) ) END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 23 mars 2023 - 21:02
TIRAR FOTO, REDUZIR O TAMANHO E SALVAR NO BANCO / / Résumé : Enregistre une photo/ / PROCEDURE PhotoEnregistre( ) path_imagem is string = fCurrentDir( ) + fSep( ) + "IMAGEM.JPG" / / ONDE VAI SALVAR A IMAGEM/ / VideoParameter( vipPhotoResolution, "1080 1080" ) VideoCapture( CAM_Appareil, path_imagem, viPictureCapture) / / TIROU A FOTO IMAGEM is Image / / IMAGEM DE TRABALHO PARA REDIMENSIONAR O BUFFER EM OUTRO TAMANHO IMAGEM = fLoadBuffer( path_imagem) IF fFileExist( path_imagem) = True THEN / / DEU CERTO Info( "A Imagem " + path_imagem+ " Existe no disco" ) dResize( IMAGEM, 320 , 480 , drStretched) / / RESIZE DA IMAGEM dSaveImageJPEG( IMAGEM, path_imagem, 80 ) / / 80 % ELSE Info( "A Imagem " + path_imagem+ " nao existe no disco" ) / / DEU ERRADO RETURN END T001_FOTOS.T001_DATA_HORA = DateSys( ) + TimeSys( ) T001_FOTOS.T001_FOTO = fLoadBuffer( path_imagem) / / BUFFER MODIFICADO E SALVO NO BINARIO IF HAdd( T001_FOTOS) = True THEN ShellExecute( path_imagem) / / GRAVOU NO BANCO E ABRIU A IMAGEM END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 08 septembre 2023 - 18:04
Compactar a imagem e daí serializar Reduzir width e heigth com dResize DsaveimageJpg por 80% E daí enviar enviar encodada Para enviar ImagemEncodada is string = encode(bufferImagem, base64) Pra voltar a ser imagem usa Buffimagem is variant = Decode(ImagemEncodada, base64) -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 06 octobre 2023 - 19:00
Para colocar o conteúdo em um buffer e depois converter em texto para transmitir via Webservice: ImagemBuf is buffer = fLoadBuffer(pathimagem) Depois converter o buffer em texto ImagemBase64 is string = Encode (ImagemBuf, base64) Estando em formato de texto só enviar normal como qualquer outro campo do banco de dados. Muito simples, e o inverso ImagemBuffer is buffer = decode(imagemBase64, base64) Img_foto = ImagemBuffer DsaveimageJpg(Img_foto, fcurrentdir()+fsep()+”foto.jpg”, 80) Mais detalhes:https://forum.pcsoft.fr/fr-FR/pcsoft.br.windev/1268-trabalhando-com-byte-array-3704/read.awp… -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 19 octobre 2023 - 16:16
Buenos dias Segue algumas dicas de como trabslhar com arquivos binários. Em resumo 1-qualquer arquivo (doc, xls, pdf, png , jpg, bmp, ico, zip, rar, certificado digital, e outros…) é igualado a um buffer ou um variant. 2-para ler um arquivo em disco e trazer o buffer dele para var você precisa do path caminho absoluto onde está ele. Exemplo: c:\meuErp\fotos\clientes\jonilton.jpg Então MyBuffer is Buffer = fLoadBuffer("c:\meuErp\fotos\clientes\jonilton.jpg") Ou MyVariant is Variant = fLoadBuffer("c:\meuErp\fotos\clientes\jonilton.jpg") 3-Apos ter o buffer de qualquer arquivo você pode fazer modificações dele. 4-Posso antes de salvar em texto modificar o tamanho, rotação, conteúdo MyImagem is imagem = myBuffer //redimensionar o tamanho MyNewImagem is imagem MyNewImagem = dResize(MyImagem, MyImagem..width/2, MyImagem..heigth/2) //metade do tamanho //rotacionar 90 graus MyNewImagem=dRotate(MyNewImagem,90) 5-se for para converter para texto ImagemString is string = encode(myBuffer, base64) Ou ImagemString is string = encode(myVariant, base64) 6-Se pegar o Buffer e guardar no tipo de campo binário, pode apontar diretamente para um controle de tela tipo: A) control de imagem para os jpg, png, bmp, ico, svg, … control WordTT para os doc e docx C) control Planilha para os xls e xlsx D) comtrol pdf para os pdf E) outros para o Edt multiline e Edt multiline RTF Ex Img_FotoCliente = MyBuffer t001_clientes.Nome = “Jonilton” t001_clientes.fotoBinaria = MyBuffer Hadd(t001_clientes) 7-Para salvar com menos dpi uma imagem então usa o comando DsaveimageJpg: DsaveimageJpg(Img_fotocliente, fcurrentdir()+fsep()+”foto.jpg”, 80) Deve ser antes de converter a imagem do disco para buffer 8-Para colocar o conteúdo em um buffer e depois converter em texto para transmitir via Webservice: ImagemBuf is buffer = fLoadBuffer(pathimagem) Depois converter o buffer em texto ImagemBase64 is string = Encode (ImagemBuf, base64) Estando em formato de texto só enviar normal como qualquer outro campo do banco de dados. Muito simples, e o inverso ImagemBuffer is buffer = decode(imagemBase64, base64) Img_foto = ImagemBuffer DsaveimageJpg(Img_foto, fcurrentdir()+fsep()+”foto.jpg”, 80) 9-o Encode converte buffer com espaços e carácteres e códigos de máquina e carácteres especiais em um array de string assim: ImagemTexto is string = “gubibihuvyuvibibibuvygigyctfdtxrxezrzaraduewyrufiibonnpnk ivhcdyfugibihhivucuvugigufubihuvyxtcyvubibboivudyxy…” Assim pode transmitir como fosse qualquer texto pelo Webservice soap ou rest !!! 10-Converter uma imagem em Thumbs PROCEDURE PhotoThumbs() path_imagem is string=fCurrentDir()+fSep()+"IMAGEM.JPG"//ONDE VAI SALVAR A IMAGEM //VideoParameter(vipPhotoResolution,"1080 1080") VideoCapture(CAM_Appareil,path_imagem,viPictureCapture)//TIROU A FOTO IMAGEM is Image//IMAGEM DE TRABALHO PARA REDIMENSIONAR O BUFFER EM OUTRO TAMANHO IMAGEM=fLoadBuffer(path_imagem) IF fFileExist(path_imagem) =TrueTHEN//DEU CERTO Info("A Imagem "+path_imagem+" Existe no disco") dResize(IMAGEM,320,480,drStretched)//RESIZE DA IMAGEM dSaveImageJPEG(IMAGEM,path_imagem,80)//80% ELSE Info("A Imagem "+path_imagem+" nao existe no disco")//DEU ERRADO RETURN END T001_FOTOS.T001_DATA_HORA=DateSys() +TimeSys() T001_FOTOS.T001_FOTO=fLoadBuffer(path_imagem)//BUFFER MODIFICADO E SALVO NO BINARIO IF HAdd(T001_FOTOS)=TrueTHEN ShellExecute(path_imagem)//GRAVOU NO BANCO E ABRIU A IMAGEM END Um detalhe importante sobre o DsaveimageJpg Salvar com 80% uma imagem de 5000kb vira 500kb e permanece a olho nu igual dSaveImageJPEG(IMAGEM,path_imagem,80)//80% -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 24 avril 2025 - 23:55
# Exemplos WLanguage para Manipulação de Imagens e Buffers Baseado no link do fórum PCsoft e nas informações encontradas, aqui estão exemplos de código em WLanguage para as funções solicitadas: ## 1. DRotate - Rotacionar uma imagem ```wlanguage // Exemplo de uso da função DRotate PROCEDURE ExemploDRotate() sImagemOriginal est une chaîne = fRepExe() + "\imagens\logo.jpg" sImagemDestino est une chaîne = fRepExe() + "\imagens\logo_rotacionado.jpg" // Carrega a imagem em uma variável Image imgLogo est une Image = sImagemOriginal // Rotaciona a imagem em 45 graus DRotate(imgLogo, 45) // Salva a imagem rotacionada dSaveImage(imgLogo, sImagemDestino, dFormatJPEG) // Exibe a imagem rotacionada em um controle Image IMG_Visualizacao = imgLogo Info("Imagem rotacionada com sucesso!") FIN ``` ## 2. DResize - Redimensionar uma imagem ```wlanguage // Exemplo de uso da função DResize PROCEDURE ExemploDResize() sImagemOriginal est une chaîne = fRepExe() + "\imagens\foto.jpg" sImagemDestino est une chaîne = fRepExe() + "\imagens\foto_redimensionada.jpg" // Carrega a imagem em uma variável Image imgFoto est une Image = sImagemOriginal // Obtém as dimensões originais nLarguraOriginal, nAlturaOriginal sont des entiers nLarguraOriginal = dGetWidth(imgFoto) nAlturaOriginal = dGetHeight(imgFoto) Info("Dimensões originais: " + nLarguraOriginal + " x " + nAlturaOriginal) // Redimensiona a imagem para metade do tamanho original DResize(imgFoto, nLarguraOriginal/2, nAlturaOriginal/2) // Salva a imagem redimensionada dSaveImage(imgFoto, sImagemDestino, dFormatJPEG) // Exibe a nova dimensão Info("Nova dimensão: " + dGetWidth(imgFoto) + " x " + dGetHeight(imgFoto)) FIN ``` ## 3. FSaveBuffer - Salvar dados de um buffer em um arquivo ```wlanguage // Exemplo de uso da função FSaveBuffer PROCEDURE ExemploFSaveBuffer() // Cria um buffer de bytes bufDados est un buffer // Preenche o buffer com alguns dados nTamanho est un entier = 1024 Dimension(bufDados, nTamanho) // Preenche o buffer com dados de exemplo (0 a 255) POUR i = 1 A nTamanho bufDados[i] = Modulo(i, 256) FIN // Define o caminho do arquivo de destino sArquivoDestino est une chaîne = fRepExe() + "\dados\meu_buffer.dat" // Salva o buffer em um arquivo SI FSaveBuffer(sArquivoDestino, bufDados) ALORS Info("Buffer salvo com sucesso em: " + sArquivoDestino) SINON Erreur("Erro ao salvar o buffer: " + ErreurInfo()) FIN FIN ``` ## 4. DLoadBuffer - Carregar uma imagem em um buffer ```wlanguage // Exemplo de uso da função DLoadBuffer PROCEDURE ExemploDLoadBuffer() // Caminho da imagem original sImagemOriginal est une chaîne = fRepExe() + "\imagens\foto.jpg" // Variável buffer para armazenar a imagem bufImagem est un buffer // Carrega a imagem para o buffer SI DLoadBuffer(bufImagem, sImagemOriginal) ALORS // Mostra o tamanho do buffer em bytes Info("Imagem carregada com sucesso. Tamanho do buffer: " + Taille(bufImagem) + " bytes") // Exemplo de manipulação do buffer (invertendo alguns bytes para efeito visual) POUR i = 1 A 1000 SI i <= Taille(bufImagem) bufImagem[i] = 255 - bufImagem[i] // Inverte os primeiros 1000 bytes FIN // Salva o buffer modificado como uma nova imagem sImagemModificada est une chaîne = fRepExe() + "\imagens\foto_modificada.jpg" SI FSaveBuffer(sImagemModificada, bufImagem) ALORS Info("Imagem modificada salva com sucesso!") SINON Erreur("Erro ao salvar a imagem modificada") FIN SINON Erreur("Erro ao carregar a imagem para o buffer") FIN FIN ``` ## 5. Exemplo combinando várias operações ```wlanguage // Exemplo combinando DRotate, DResize, DLoadBuffer e FSaveBuffer PROCEDURE ExemploCombinado() // Caminho dos arquivos sImagemOriginal est une chaîne = fRepExe() + "\imagens\foto_original.jpg" sImagemProcessada est une chaîne = fRepExe() + "\imagens\foto_processada.jpg" // Carrega a imagem em uma variável Image imgFoto est une Image = sImagemOriginal // Aplica uma rotação de 90 graus DRotate(imgFoto, 90) // Redimensiona para 800x600 DResize(imgFoto, 800, 600) // Salva a imagem processada dSaveImage(imgFoto, sImagemProcessada, dFormatJPEG) // Agora vamos carregar a imagem processada em um buffer bufImagem est un buffer SI DLoadBuffer(bufImagem, sImagemProcessada) ALORS // Aplica um filtro simples (invertendo os primeiros 100 bytes como exemplo) POUR i = 1 A 100 SI i <= Taille(bufImagem) bufImagem[i] = 255 - bufImagem[i] FIN // Salva o buffer modificado como uma nova imagem sImagemFinal est une chaîne = fRepExe() + "\imagens\foto_final.jpg" SI FSaveBuffer(sImagemFinal, bufImagem) ALORS Info("Processo completo! Imagem final salva em: " + sImagemFinal) SINON Erreur("Erro ao salvar a imagem final") FIN SINON Erreur("Erro ao carregar a imagem em buffer") FIN FIN ``` ## 6. Exemplo de processamento de múltiplas imagens em lote ```wlanguage // Exemplo de processamento em lote usando as funções solicitadas PROCEDURE ProcessarImagensEmLote(sPastaOrigem est une chaîne, sPastaDestino est une chaîne) // Verifica se as pastas existem SI fRepExiste(sPastaOrigem) = Faux ALORS Erreur("A pasta de origem não existe!") RETOUR FIN // Cria a pasta de destino se não existir SI fRepExiste(sPastaDestino) = Faux ALORS fRepCrée(sPastaDestino) FIN // Obtém a lista de arquivos JPG na pasta de origem tabArquivos est un tableau de chaînes tabArquivos = fListeFichier(sPastaOrigem + "\*.jpg", frArchive) // Para cada arquivo, aplica o processamento POUR TOUT sArquivo DE tabArquivos // Caminho completo do arquivo sOrigem est une chaîne = sPastaOrigem + "\" + sArquivo sDestino est une chaîne = sPastaDestino + "\" + sArquivo // Carrega a imagem imgTemp est une Image = sOrigem // Aplica uma rotação de 180 graus DRotate(imgTemp, 180) // Redimensiona para 50% do tamanho original nLargura, nAltura sont des entiers nLargura = dGetWidth(imgTemp) nAltura = dGetHeight(imgTemp) DResize(imgTemp, nLargura/2, nAltura/2) // Salva a imagem processada dSaveImage(imgTemp, sDestino, dFormatJPEG) // Libera a memória imgTemp = Null FIN Info(tabArquivos.Occurrence + " imagens processadas com sucesso!") FIN ``` Estes exemplos demonstram o uso das funções DRotate, DResize, FSaveBuffer e DLoadBuffer do WLanguage para manipulação de imagens e buffers de dados. As funções permitem rotacionar e redimensionar imagens, além de carregar e salvar dados em buffers. Você pode adaptar estes exemplos para suas necessidades específicas, ajustando parâmetros como ângulos de rotação, dimensões e caminhos de arquivo. -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 24 avril 2025 - 23:58
Novos exemplos 1. Criando um Carrossel de Imagens com Rotação Dinâmica (`DRotate`) Cenário: Um aplicativo exibe um carrossel de imagens promocionais que giram levemente para criar um efeito visual atrativo antes de serem exibidas em um controle de imagem. PROCEDURE CriarCarrosselImagem(sCaminhoImagem est une chaîne) // Carrega a imagem original imgPromocao est une Image = sCaminhoImagem SI imgPromocao = Nul ALORS Erreur("Erro ao carregar a imagem: " + sCaminhoImagem) RETOUR FIN // Cria um efeito de rotação suave (de -15° a +15° em 5 passos) POUR i = -15 A 15 PAR PAS 7.5 imgTemp est une Image = imgPromocao DRotate(imgTemp, i) // Rotaciona a imagem // Salva a imagem rotacionada temporariamente sArquivoTemp est une chaîne = fRepTemp() + "\carrossel_" + ChaîneConstruit("%1.jpg", i) dSaveImage(imgTemp, sArquivoTemp, dFormatJPEG) // Exibe a imagem no controle com uma pequena pausa para animação IMG_Carrossel = sArquivoTemp Pause(100) // Pausa de 100ms para efeito visual FIN // Exibe a imagem original no final IMG_Carrossel = imgPromocao Info("Carrossel de rotação concluído!") FIN Diferencial: Este exemplo cria um efeito visual de carrossel com rotações graduais, ideal para interfaces de usuário interativas, como em aplicativos promocionais ou galleries. 2. Redimensionamento para Thumbnails de Perfil com Moldura (`DResize`) Cenário: Um sistema de cadastro de usuários redimensiona fotos de perfil para um tamanho padrão (150x150) e adiciona uma moldura circular estilizada. PROCEDURE CriarThumbnailPerfil(sImagemOriginal est une chaîne, sImagemDestino est une chaîne) // Carrega a imagem original imgPerfil est une Image = sImagemOriginal SI imgPerfil = Nul ALORS Erreur("Erro ao carregar a imagem: " + sImagemOriginal) RETOUR FIN // Redimensiona para 150x150 pixels, mantendo proporção DResize(imgPerfil, 150, 150, drHomotheticCentered) // Carrega uma moldura circular (um PNG com fundo transparente) sMoldura est une chaîne = fRepExe() + "\recursos\moldura_circular.png" imgMoldura est une Image = sMoldura // Combina a imagem redimensionada com a moldura dDrawImage(imgPerfil, imgMoldura, 0, 0) // Salva a imagem final com a moldura dSaveImage(imgPerfil, sImagemDestino, dFormatPNG) SI fFichierExiste(sImagemDestino) ALORS Info("Thumbnail de perfil com moldura salvo em: " + sImagemDestino) SINON Erreur("Erro ao salvar o thumbnail") FIN // Exibe no controle de imagem IMG_Perfil = sImagemDestino FIN Diferencial: Este exemplo combina DResize com composição de imagens, criando thumbnails estilizados com uma moldura, ideal para sistemas de gerenciamento de usuários ou redes sociais. 3. Salvando um Relatório em PDF como Buffer (`FSaveBuffer`) Cenário: Um sistema gera um relatório em PDF, o converte para um buffer e o salva em um arquivo temporário para envio posterior via e-mail. PROCEDURE SalvarRelatorioPDFComoBuffer() // Gera um relatório em PDF (exemplo fictício) sArquivoPDF est une chaîne = fRepTemp() + "\relatorio.pdf" PDFCréeDocument("Relatório Mensal") PDFAjouteTexte("Vendas de Abril 2025: R$ 100.000") PDFSauve(sArquivoPDF) // Carrega o PDF em um buffer bufRelatorio est un buffer SI DLoadBuffer(bufRelatorio, sArquivoPDF) ALORS Info("Relatório PDF carregado em buffer. Tamanho: " + Taille(bufRelatorio) + " bytes") // Salva o buffer em um novo arquivo para verificação sArquivoDestino est une chaîne = fRepTemp() + "\relatorio_copia.pdf" SI FSaveBuffer(sArquivoDestino, bufRelatorio) ALORS Info("Cópia do relatório salva em: " + sArquivoDestino) // Simula envio por e-mail (apenas log) EmailPrepare("relatorios@empresa.com", "Relatório Mensal", "Relatório em anexo", sArquivoDestino) Info("Relatório preparado para envio por e-mail") SINON Erreur("Erro ao salvar o buffer do relatório") FIN SINON Erreur("Erro ao carregar o relatório em buffer") FIN FIN Diferencial: Este exemplo demonstra o uso de FSaveBuffer para manipular arquivos PDF, com um caso prático de geração e envio de relatórios, algo comum em sistemas corporativos. 4. Criando um Filtro de Imagem Estilizado (`DLoadBuffer`) Cenário: Um aplicativo permite que o usuário aplique um filtro monocromático a uma foto, manipulando os bytes da imagem diretamente no buffer. PROCEDURE AplicarFiltroMonocromatico(sImagemOriginal est une chaîne, sImagemDestino est une chaîne) // Carrega a imagem em um buffer bufImagem est un buffer SI DLoadBuffer(bufImagem, sImagemOriginal) ALORS // Aplica um filtro monocromático simples (média dos canais RGB) imgOriginal est une Image = bufImagem nTamanho est un entier = Taille(bufImagem) // Manipula o buffer diretamente (exemplo simplificado) POUR i = 1 A nTamanho PAR PAS 3 SI i + 2 <= nTamanho // Calcula a média dos canais RGB nMedia est un entier = (bufImagem[i] + bufImagem[i+1] + bufImagem[i+2]) / 3 bufImagem[i] = nMedia // Vermelho bufImagem[i+1] = nMedia // Verde bufImagem[i+2] = nMedia // Azul FIN // Salva o buffer modificado como uma novaimagem SI FSaveBuffer(sImagemDestino, bufImagem) ALORS Info("Imagem monocromática salva em: " + sImagemDestino) IMG_FotoFiltro = sImagemDestino SINON Erreur("Erro ao salvar a imagem com filtro") FIN SINON Erreur("Erro ao carregar a imagem em buffer") FIN FIN Diferencial: Este exemplo manipula diretamente os bytes da imagem no buffer para criar um filtro monocromático, explorando um caso de uso criativo para edição de imagens em tempo real. 5. Processamento de Imagens para um Catálogo Digital (`DRotate`, `DResize`, `FSaveBuffer`, `DLoadBuffer`) Cenário: Um sistema de e-commerce processa imagens de produtos, aplicando rotação para corrigir orientação, redimensionando para tamanhos específicos e salvando em um buffer para upload em um webservice. PROCEDURE ProcessarImagemProduto(sImagemOriginal est une chaîne, nAnguloCorrecao est un réel) // Define os caminhos sImagemProcessada est une chaîne = fRepTemp() + "\produto_processado.jpg" // Carrega a imagem imgProduto est une Image = sImagemOriginal SI imgProduto = Nul ALORS Erreur("Erro ao carregar a imagem do produto") RETOUR FIN // Corrige a orientação com rotação DRotate(imgProduto, nAnguloCorrecao) // Redimensiona para 600x600 pixels, mantendo proporção DResize(imgProduto, 600, 600, drHomotheticCentered) // Salva a imagem processada temporariamente dSaveImage(imgProduto, sImagemProcessada, dFormatJPEG, 80) // Carrega a imagem processada em um buffer bufImagem est un buffer SI DLoadBuffer(bufImagem, sImagemProcessada) ALORS // Converte o buffer para Base64 para envio ao webservice sImagemBase64 est une chaîne = Encode(bufImagem, encodeBASE64) // Simula o envio ao webservice req est une httpRequest req.URL = "https://api.ecommerce.com/uploadImagem " req.Méthode = httpPost req.Contenu = "imagem=" + sImagemBase64 reponse est une httpResponse = HTTPSend(req) SI ErreurSurvenue ALORS Erreur("Erro ao enviar imagem ao webservice: " + ErreurInfo()) SINON Info("Imagem enviada com sucesso! Resposta: " + reponse..Contenu) FIN // Salva o buffer localmente como backup sBackup est une chaîne = fRepExe() + "\backup\produto_" + DateSys() + ".jpg" SI FSaveBuffer(sBackup, bufImagem) ALORS Info("Backup da imagem salvo em: " + sBackup) SINON Erreur("Erro ao salvar o backup") FIN SINON Erreur("Erro ao carregar a imagem em buffer") FIN FIN Diferencial: Este exemplo integra todas as funções solicitadas em um fluxo completo de processamento de imagens para e-commerce, incluindo correção de orientação, redimensionamento, conversão para Base64 e backup, refletindo um caso realista de integração com APIs. 6. Gerador de Miniaturas para Visualização Offline (`DResize`, `DLoadBuffer`, `FSaveBuffer`) Cenário: Um aplicativo móvel cria miniaturas de imagens para visualização offline, armazenando-as em uma pasta local com tamanho reduzido para economizar espaço. PROCEDURE GerarMiniaturasOffline(sPastaImagens est une chaîne, sPastaMiniaturas est une chaîne) // Cria a pasta de miniaturas, se não existir SI fRepExiste(sPastaMiniaturas) = Faux ALORS fRepCrée(sPastaMiniaturas) FIN // Lista todas as imagens JPG na pasta tabImagens est un tableau de chaînes = fListeFichier(sPastaImagens + "\*.jpg", frArchive) SI tabImagens.Occurrence = 0 ALORS Info("Nenhuma imagem encontrada na pasta: " + sPastaImagens) RETOUR FIN // Processa cada imagem POUR TOUT sImagem DE tabImagens sCaminhoImagem est une chaîne = sPastaImagens + "\" + sImagem sCaminhoMiniatura est une chaîne = sPastaMiniaturas + "\thumb_" + sImagem // Carrega a imagem em um buffer bufImagem est un buffer SI DLoadBuffer(bufImagem, sCaminhoImagem) ALORS // Carrega o buffer em uma variável Image para redimensionamento imgMiniatura est une Image = bufImagem // Redimensiona para 100x100 pixels DResize(imgMiniatura, 100, 100, drHomotheticCentered) // Salva a miniatura temporariamente sTemp est une chaîne = fRepTemp() + "\temp_thumb.jpg" dSaveImage(imgMiniatura, sTemp, dFormatJPEG, 70) // Carrega a miniatura em um novo buffer e salva na pasta final bufMiniatura est un buffer SI DLoadBuffer(bufMiniatura, sTemp) ALORS SI FSaveBuffer(sCaminhoMiniatura, bufMiniatura) ALORS Info("Miniatura gerada: " + sCaminhoMiniatura) SINON Erreur("Erro ao salvar miniatura: " + sCaminhoMiniatura) FIN SINON Erreur("Erro ao carregar miniatura em buffer") FIN SINON Erreur("Erro ao carregar imagem em buffer: " + sCaminhoImagem) FIN FIN Info("Processamento concluído! " + tabImagens.Occurrence + " miniaturas geradas.") FIN Diferencial: Este exemplo foca em otimização para dispositivos móveis, gerando miniaturas leves para visualização offline, com uso eficiente de buffers e redimensionamento para economizar espaço. Notas Finais • Criatividade: Cada exemplo foi projetado para abordar um caso de uso diferente, como animações visuais, composição de imagens, filtros, relatórios, e-commerce e otimização para dispositivos móveis, evitando repetições dos exemplos do fórum. • Funcionalidade: Os códigos são completos e podem ser adaptados para projetos reais, com tratamento de erros e comentários explicativos. • Flexibilidade: Os exemplos podem ser modificados para diferentes formatos de imagem (PNG, JPEG), tamanhos, ângulos ou integrações com outros sistemas (webservices, bancos de dados HFSQL, etc.). • Conformidade: Segui rigorosamente as instruções, focando nas funções solicitadas (DRotate, DResize, FSaveBuffer, DLoadBuffer) e mantendo a originalidade em relação ao conteúdo do fórum. Se precisar de ajustes, mais exemplos ou integração com outros recursos do WLanguage (como webservices ou HFSQL), é só avisar! 🚀 -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 25 avril 2025 - 00:00
Exemplo de salvamento de arquivo em HFSQL Para armazenar arquivos (PDF, DOCX etc.) no banco HFSQL, use um campo do tipo Memo (que aceita dados binários) . A estrutura de dados pode ser, por exemplo, uma tabela Documentos com campos ID (chave auto-incremental), NomeDoc (nome do arquivo) e Conteudo (Memo). Exemplo de criação via código WLanguage: // Cria tabela HFSQL (cliente/servidor). Ajuste o nome da conexão conforme necessário. HExecuteSQLQuery("MinhaConexao", "CriarTabela", "CREATE TABLE Documentos ("+ " ID INT AUTO, "+ " NomeDoc VARCHAR(255), "+ " Conteudo MEMO"+ ")") Passos gerais: • Criar a tabela com campo Conteudo do tipo Memo (suporta objetos binários: imagens, documentos, etc.) . • No código do WinDev, usar fSelect para abrir um seletor de arquivos e obter o caminho (retorna string) . • Carregar o arquivo em uma variável do tipo Buffer usando fLoadBuffer(caminhoArquivo) . Essa função lê o conteúdo (binário) do arquivo. • Preencher o registro (por exemplo, Documentos.NomeDoc = fFileName(caminho) e Documentos.Conteudo = meuBuffer) e usar HAdd(Documentos) para salvar no HFSQL. • Para recuperar o arquivo do banco, use HReadSeek (ou outra leitura) para localizar o registro, depois chame fSaveBuffer(caminhoDestino, Documentos.Conteudo)  para gravar o buffer em disco e permitir a visualização ou exportação. Abaixo segue um exemplo completo de código (WLanguage) para WinDev/WinDev Mobile. Os comandos são os mesmos em ambas as plataformas: // Botão "Salvar Arquivo" - seleciona arquivo e grava no HFSQL PROCEDURE BotaoSalvarClicado() // 1. Seleciona o arquivo com fSelect (apenas arquivos existentes) [oai_citation:5‡doc.pcsoft.fr](https://doc.pcsoft.fr/en-US/?1000003036053&name=fselect_example#:~:text=%2F%2F%20Select%20file%20to%20open,no%20file%20was%20opened%20IF%C2%A0FileID%C2%A0%3D%C2%A01%C2%A0THEN ) sCaminhoArquivo is string = fSelect( "", // diretório inicial ("" = pasta atual) "*.*", // máscara inicial "Selecione um arquivo",// título do diálogo "Todos os arquivos (*.*)" + TAB + "*.*", // filtros de arquivo "", // extensão padrão fSelOpen + fSelExist // modo: abrir somente existente ) IF sCaminhoArquivo = "" THEN INFO("Nenhum arquivo selecionado.") RETURN END // 2. Carrega o conteúdo do arquivo em um buffer [oai_citation:6‡doc.pcsoft.fr](https://doc.pcsoft.fr/en-us/?1000019410&name=floadbuffer_function&product=WM#:~:text=Loads%20the%20content%20of%20an,in%20a%20buffer%20variable ) meuBuffer is Buffer = fLoadBuffer(sCaminhoArquivo) IF ErrorOccurred THEN Error("Falha ao carregar o arquivo.") RETURN END // 3. Preenche o registro e salva no HFSQL Documentos.NomeDoc = fFileName(sCaminhoArquivo) // nome do arquivo (com extensão) Documentos.Conteudo = meuBuffer // campo MEMO recebe o buffer IF HAdd(Documentos) = False THEN Error("Erro ao gravar no banco de dados.") ELSE INFO("Arquivo salvo com sucesso no banco!") END END // Botão "Abrir Arquivo" - recupera do banco e salva em disco para visualizar PROCEDURE BotaoAbrirClicado() // Supondo que temos o ID do registro a ser recuperado (ex: 123) nID is int = Val(InputString("ID do documento:"), 0) IF nID = 0 THEN Error("ID inválido.") RETURN END // 1. Lê o registro pelo ID IF HReadSeek(Documentos, Documentos.ID, nID) = False THEN Error("Documento não encontrado.") RETURN END // 2. Grava o conteúdo binário em arquivo local usando fSaveBuffer [oai_citation:7‡doc.pcsoft.fr](https://doc.pcsoft.fr/en-US/?3036006&product=WB#:~:text=Loads%20the%20contents%20of%20a,this%20file%20from%20the%20buffer ) sSalvarEm is string = fCurrentDir()+fSep()+"exportado_"+Documentos.NomeDoc IF fSaveBuffer(sSalvarEm, Documentos.Conteudo) = False THEN Error("Erro ao salvar o arquivo no disco.") ELSE Info("Arquivo recuperado e salvo em: "+sSalvarEm) // Em WinDev Desktop, podemos abrir com o programa padrão: IF WinExec("explorer.exe /select,"+sSalvarEm) = False THEN Trace("Não foi possível abrir o arquivo automaticamente.") END END END Explicação resumida: 1. Seleção de arquivo: fSelect abre o diálogo de arquivos para o usuário escolher o PDF/DOCX . 2. Leitura binária: fLoadBuffer carrega todo o conteúdo do arquivo em um Buffer . Esse buffer contém os bytes do arquivo. 3. Gravação no HFSQL: Preenche-se o campo Memo (Documentos.Conteudo) com esse buffer e usa-se HAdd para inserir o registro. O campo NomeDoc armazena apenas o nome (usamos fFileName para extrair o nome). 4. Recuperação do arquivo: Consulta-se o registro (por ex. por ID) via HReadSeek. O conteúdo do campo Memo é lido para um buffer automaticamente. Em seguida, fSaveBuffer grava esse buffer em um novo arquivo no disco . O arquivo gerado (exportado_nome.ext) pode ser aberto ou exportado conforme necessidade. Este código funciona tanto em aplicações WinDev Desktop quanto em WinDev Mobile (observando que, em mobile, o acesso ao sistema de arquivos pode exigir caminhos especiais; em geral, leia de áreas permitidas pelo app). O uso do campo Memo garante que qualquer arquivo binário seja armazenado corretamente no banco . As funções fLoadBuffer e fSaveBuffer simplificam a conversão entre arquivo e campo binário  . Referências: Manuais PC SOFT (fSelect, fLoadBuffer, fSaveBuffer)   , e definições de campo Memo no HFSQL . -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/
Membre enregistré 3 860 messages
Posté le 25 avril 2025 - 00:12
Claro! Aqui estão os scripts SQL individuais para a criação da tabela imagem_arquivos em cada banco de dados (MySQL, PostgreSQL, SQL Server, Oracle e Teradata), todos apresentados como texto isolado, prontos para uso direto: ⸻ 1. MySQL CREATE TABLE imagem_arquivos ( id INT AUTO_INCREMENT PRIMARY KEY, nome_arquivo VARCHAR(255), conteudo LONGBLOB ); ⸻ 2. PostgreSQL CREATE TABLE imagem_arquivos ( id SERIAL PRIMARY KEY, nome_arquivo VARCHAR(255), conteudo BYTEA ); ⸻ 3. SQL Server CREATE TABLE imagem_arquivos ( id INT IDENTITY(1,1) PRIMARY KEY, nome_arquivo NVARCHAR(255), conteudo VARBINARY(MAX) ); ⸻ 4. Oracle CREATE TABLE imagem_arquivos ( id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, nome_arquivo VARCHAR2(255), conteudo BLOB ); ⸻ 5. Teradata CREATE TABLE imagem_arquivos ( id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, nome_arquivo VARCHAR(255), conteudo BLOB ); ⸻ Perfeito! Abaixo estão procedures completas em WLanguage (WX) para salvar uma imagem no banco de dados, uma para cada tipo de banco: MySQL, PostgreSQL, SQL Server, Oracle e Teradata: ⸻ Pré-requisitos comuns • A tabela imagem_arquivos já deve estar criada com os campos id, nome_arquivo, conteudo. • Conexões devem estar configuradas previamente com nomes de conexão como MySQLConexao, PostgresConexao, etc. • A imagem será lida do disco com fLoadBuffer. ⸻ 1. MySQL - Procedure //====================================================================================== // Procedure..: SalvarImagem_MySQL // Descrição..: Salva uma imagem no banco de dados MySQL //====================================================================================== PROCEDURE SalvarImagem_MySQL(psCaminhoImagem is string) bufImagem is Buffer = fLoadBuffer(psCaminhoImagem) IF ErrorOccurred THEN Error("Erro ao carregar a imagem.") RETURN END sNomeArquivo is string = fExtractPath(psCaminhoImagem, fFileName) sSQL is string = [ INSERT INTO imagem_arquivos (nome_arquivo, conteudo) VALUES (?, ?) ] IF NOT SQLConnect("MySQLConexao") THEN Error(SQL.MensagemErro) RETURN END qry is Data Source IF SQLPrepare(qry, sSQL, "MySQLConexao") THEN SQLSetParam(qry, 1, sNomeArquivo) SQLSetParam(qry, 2, bufImagem) IF NOT SQLExecute(qry) THEN Error(SQL.MensagemErro) ELSE Info("Imagem salva com sucesso no MySQL.") END ELSE Error(SQL.MensagemErro) END ⸻ 2. PostgreSQL - Procedure //====================================================================================== // Procedure..: SalvarImagem_PostgreSQL // Descrição..: Salva uma imagem no PostgreSQL //====================================================================================== PROCEDURE SalvarImagem_PostgreSQL(psCaminhoImagem is string) bufImagem is Buffer = fLoadBuffer(psCaminhoImagem) IF ErrorOccurred THEN Error("Erro ao carregar a imagem.") RETURN END sNomeArquivo is string = fExtractPath(psCaminhoImagem, fFileName) sSQL is string = [ INSERT INTO imagem_arquivos (nome_arquivo, conteudo) VALUES (?, ?) ] IF NOT SQLConnect("PostgresConexao") THEN Error(SQL.MensagemErro) RETURN END qry is Data Source IF SQLPrepare(qry, sSQL, "PostgresConexao") THEN SQLSetParam(qry, 1, sNomeArquivo) SQLSetParam(qry, 2, bufImagem) IF NOT SQLExecute(qry) THEN Error(SQL.MensagemErro) ELSE Info("Imagem salva com sucesso no PostgreSQL.") END ELSE Error(SQL.MensagemErro) END ⸻ 3. SQL Server - Procedure //====================================================================================== // Procedure..: SalvarImagem_SQLServer // Descrição..: Salva uma imagem no SQL Server //====================================================================================== PROCEDURE SalvarImagem_SQLServer(psCaminhoImagem is string) bufImagem is Buffer = fLoadBuffer(psCaminhoImagem) IF ErrorOccurred THEN Error("Erro ao carregar a imagem.") RETURN END sNomeArquivo is string = fExtractPath(psCaminhoImagem, fFileName) sSQL is string = [ INSERT INTO imagem_arquivos (nome_arquivo, conteudo) VALUES (?, ?) ] IF NOT SQLConnect("SQLServerConexao") THEN Error(SQL.MensagemErro) RETURN END qry is Data Source IF SQLPrepare(qry, sSQL, "SQLServerConexao") THEN SQLSetParam(qry, 1, sNomeArquivo) SQLSetParam(qry, 2, bufImagem) IF NOT SQLExecute(qry) THEN Error(SQL.MensagemErro) ELSE Info("Imagem salva com sucesso no SQL Server.") END ELSE Error(SQL.MensagemErro) END ⸻ 4. Oracle - Procedure //====================================================================================== // Procedure..: SalvarImagem_Oracle // Descrição..: Salva uma imagem no banco de dados Oracle //====================================================================================== PROCEDURE SalvarImagem_Oracle(psCaminhoImagem is string) bufImagem is Buffer = fLoadBuffer(psCaminhoImagem) IF ErrorOccurred THEN Error("Erro ao carregar a imagem.") RETURN END sNomeArquivo is string = fExtractPath(psCaminhoImagem, fFileName) sSQL is string = [ INSERT INTO imagem_arquivos (nome_arquivo, conteudo) VALUES (?, ?) ] IF NOT SQLConnect("OracleConexao") THEN Error(SQL.MensagemErro) RETURN END qry is Data Source IF SQLPrepare(qry, sSQL, "OracleConexao") THEN SQLSetParam(qry, 1, sNomeArquivo) SQLSetParam(qry, 2, bufImagem) IF NOT SQLExecute(qry) THEN Error(SQL.MensagemErro) ELSE Info("Imagem salva com sucesso no Oracle.") END ELSE Error(SQL.MensagemErro) END ⸻ 5. Teradata - Procedure //====================================================================================== // Procedure..: SalvarImagem_Teradata // Descrição..: Salva uma imagem no banco de dados Teradata //====================================================================================== PROCEDURE SalvarImagem_Teradata(psCaminhoImagem is string) bufImagem is Buffer = fLoadBuffer(psCaminhoImagem) IF ErrorOccurred THEN Error("Erro ao carregar a imagem.") RETURN END sNomeArquivo is string = fExtractPath(psCaminhoImagem, fFileName) sSQL is string = [ INSERT INTO imagem_arquivos (nome_arquivo, conteudo) VALUES (?, ?) ] IF NOT SQLConnect("TeradataConexao") THEN Error(SQL.MensagemErro) RETURN END qry is Data Source IF SQLPrepare(qry, sSQL, "TeradataConexao") THEN SQLSetParam(qry, 1, sNomeArquivo) SQLSetParam(qry, 2, bufImagem) IF NOT SQLExecute(qry) THEN Error(SQL.MensagemErro) ELSE Info("Imagem salva com sucesso no Teradata.") END ELSE Error(SQL.MensagemErro) END ⸻ Essas procedures seguem o mesmo padrão para todos os bancos, permitindo manutenção fácil, segurança via parametrização SQL, e uso de conexões configuradas. -- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianobollerhttp://wxinformatica.com.br/