Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Desarrollo en Delphi para Android
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos


Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
ImgToBase64

hola como están.
Estoy trabajando en Ex8 realizando una app para Android, el cual necesito subir fotos desde el dispositivo.
Mi idea sería convertirla a base64, y enviarla a un servidor para guardarlo en una base de datos.
Cuando consulte la foto el servidor me devuelve el base64 y la decodifico nuevamente en la app.
He buscado por todas partes pero la verdad que no he podido obtener un buen resultado, ya que siempre me da error en alguna parte.
En otro caso como puedo hacer para enviar una foto y que el servidor me la codifique, (el servidor es en nodejs).
Esas fueron las opciones que estuve estudiando tal vez existe alguna otra y no lo sé.
Para enviar vía json tengo que codificarla si no me equivoco no?
Desde ya agradezco quien me pueda aportar algo.

Saludos.
Responder Con Cita
  #2  
Antiguo 12-03-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.037
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por D1360666 Ver Mensaje
... no he podido obtener un buen resultado, ya que siempre me da error en alguna parte.
¿Algo más explícito?, gracias.
Por cierto, para otra vez, intenta poner un título descriptivo a tu pregunta, gracias.
Responder Con Cita
  #3  
Antiguo 12-03-2016
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.267
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
A mi me parece una buena opción.

¿Dónde está el error? ¿En la codificación, en la decodificación?
¿Qué librería estás utilizando para hacerlo?
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 12-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
En el foro he visto que usan la api de Windows pero siendo para Android no creo que me sirva mucho.
Estuve mirando los componentes encodermime y decodermime no se si estoy en lo correcto. Lo que necesito es como codificar y decodificar la imagen en la aplicación así luego se la envío a node como base 64 y el servidor se encarga de realizar el sql con la bd.
Espero haber sido más explícito en mi respuesta. Desde ya agradezco los aportes
Responder Con Cita
  #5  
Antiguo 13-03-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
No has comentado que error te da y que biblioteca estas usando

Como ya se hablo hace no mucho, existen varias formas en Delphi de trabajar con Base64

El problema que tenes puede que sea por el Encoding; basicamente Base64 codifica/decodifica bytes, no necesariamente texto (string, caracteres), asi que hay que "elegir" un encoding cuando se realiza el proceso

Revisa estos links que hay diferentes codigos de ejemplo, usando las bibliotecas de Indy, Soap y NetEncoding

Results of DecodeBase64 only 1 Byte on Android?

BASE64 Encode and Decode is not working
Responder Con Cita
  #6  
Antiguo 13-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
Gracias voy a revisar los links. Con soap vi q hay una libreria encdcd algo así pero como tengo un server nodejs en lugar de soap utilizo el componente tidhttp con sus funciones post get. Me ha parecido más sencillo en el tema comunicación pero me complique con esto q nunca utilicé. Lo que había probado era cargar la imagen como un stream y con encodermime codificarlo pero no se si está bien la idea.
Desde ya gracias por los aportes.
Responder Con Cita
  #7  
Antiguo 14-03-2016
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Independientemente de las librerías que puedan usarse, me he tomado la libertad de escribir una Unit para codificar y decodificar en BASE64 sin utilizar la API de Windows ni librerías de terceros.

Dejo aquí el código:
Código Delphi [-]
unit BASE64;

interface

type
  TAByte = Array of Byte;
  PAByte = ^TAByte;

  function Decode64(S: String): TAByte;
  function Encode64(Bin: PByte; Count: integer): String;

implementation

const
 SB64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

type
  SAByte = Array[0..0] of Byte;
  PSAByte = ^SAByte;

function find(C: CHAR): integer;
begin
  Result:= 0;
  while (SB64[Result+1] <> C) and (Result < 64) do inc(Result);
end;

function Decode64(S: String): TAByte;
var
  B0, B1, B2, B3: BYTE;
  L, n, i: integer;
begin
  n:= 1;
  i:= 0;
  L:= Length(S);
  SetLength(Result, (Length(S)*3) div 4);
  repeat
    B0:= find(S[n]);
    B1:= find(S[n+1]);
    B2:= find(S[n+2]);
    B3:= find(S[n+3]);

    Result[i]:=   (B0 shl 2) or (B1 shr 4);
    if B2 = 64 then break;
    Result[i+1]:= (B1 shl 4) or (B2 shr 2);
    if B3 = 64 then break;
    Result[i+2]:= (B2 shl 6) or B3;
    inc(n, 4);
    inc(i, 3);
  until n>L;
end;


function Encode64(Bin: PByte; Count: integer): String;
var
  B0, B1, B2: BYTE;
  ABin: PSAByte;
  Add, L, n, i: integer;
begin
  if Count = 0 then exit;
  ABin:= PSAByte(Bin);
  n:= 0;
  i:=1;
  L:= ((Count+2) div 3)*4;
  SetLength(Result, L);
  repeat
    B0:= ABin^[n];
    B1:= 0; B2:= 0;
    if (Count - n) > 0 then B1:= ABin^[n+1];
    if (Count - n) > 1 then B2:= ABin^[n+2];
    Result[i]:=   SB64[(B0 shr 2) and $003F +1];
    Result[i+1]:= SB64[((B0 shl 4) or (B1 shr 4)) and $003F +1];
    Result[i+2]:= SB64[((B1 shl 2) or (B2 shr 6)) and $003F +1];
    Result[i+3]:= SB64[(B2 and $3F) +1];
    inc(n,3);
    inc(i,4);
  until n >= Count;
  if n - Count >= 1 then Result[L]:=   '=';
  if n - Count = 2  then Result[L-1]:= '=';
end;

end.

Espero que sea de utilidad.


Saludos.
Responder Con Cita
  #8  
Antiguo 14-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
Net Encoding me parece la mejor opción, estoy revisando como funcionaría exactamente, y ni bien tenga funcionando(si lo logro), subo el ejemplo.
Responder Con Cita
  #9  
Antiguo 14-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
Perdón no había visto el ejemplo, lo voy a probar, muchas gracias por el aporte!!
Responder Con Cita
  #10  
Antiguo 14-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
En ese caso lo que tendría que hacer sería pasar a cadena de texto el stream imagen y codifiicarla o decodificarla no?
Responder Con Cita
  #11  
Antiguo 14-03-2016
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Las funciones codifican y de codifican. En el caso de un stream, éste se usará para el buffer binario. Las funciones se pueden modificar para aceptar stream en lugar de un array. He usado un array para que el código sea totalmente independiente de elementos externos al mismo, como la propia VCL.

Saludos.
Responder Con Cita
  #12  
Antiguo 15-03-2016
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Hay un bug en la unit BASE64, concretamente en Decode64, que no afecta al funcionamiento pero si altera en 1 o 2 bytes el tamaño del buffer. Vuelvo a publicar la unit completa y un ejemplo de como conseguir usar Streams.
Código Delphi [-]
unit BASE64;

interface

type
  TAByte = Array of Byte;
  PAByte = ^TAByte;

  function Decode64(S: String): TAByte;
  function Encode64(Bin: PByte; Count: integer): String;

implementation

const
 SB64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

type
  SAByte = Array[0..0] of Byte;
  PSAByte = ^SAByte;

function find(C: CHAR): integer;
begin
  Result:= 0;
  while (SB64[Result+1] <> C) and (Result < 64) do inc(Result);
end;

function Decode64(S: String): TAByte;
var
  B0, B1, B2, B3: BYTE;
  L, n, i: integer;
begin
  n:= 1;
  i:= 0;
  L:= Length(S);
  if S[L] = '=' then dec(L);
  if S[L] = '=' then dec(L);
  SetLength(Result, (L*3) div 4);
  repeat
    B0:= find(S[n]);
    B1:= find(S[n+1]);
    B2:= find(S[n+2]);
    B3:= find(S[n+3]);

    Result[i]:=   (B0 shl 2) or (B1 shr 4);
    if B2 = 64 then break;
    Result[i+1]:= (B1 shl 4) or (B2 shr 2);
    if B3 = 64 then break;
    Result[i+2]:= (B2 shl 6) or B3;
    inc(n, 4);
    inc(i, 3);
  until n>L;
end;


function Encode64(Bin: PByte; Count: integer): String;
var
  B0, B1, B2: BYTE;
  ABin: PSAByte;
  Add, L, n, i: integer;
begin
  if Count = 0 then exit;
  ABin:= PSAByte(Bin);
  n:= 0;
  i:=1;
  L:= ((Count+2) div 3)*4;
  SetLength(Result, L);
  repeat
    B0:= ABin^[n];
    B1:= 0; B2:= 0;
    if (Count - n) > 0 then B1:= ABin^[n+1];
    if (Count - n) > 1 then B2:= ABin^[n+2];
    Result[i]:=   SB64[(B0 shr 2) and $003F +1];
    Result[i+1]:= SB64[((B0 shl 4) or (B1 shr 4)) and $003F +1];
    Result[i+2]:= SB64[((B1 shl 2) or (B2 shr 6)) and $003F +1];
    Result[i+3]:= SB64[(B2 and $3F) +1];
    inc(n,3);
    inc(i,4);
  until n >= Count;
  if n - Count >= 1 then Result[L]:=   '=';
  if n - Count = 2  then Result[L-1]:= '=';
end;

end.

Para usar TMemoryStream sin modificar la Unit puedes implementar algo como esto:
Código Delphi [-]
function StreamEncode64(var MStream: TMemoryStream): string;
begin
  Result:= Encode64(MStream.Memory, MStream.Size);
end;

procedure StreamDencode64(var S: String; var MStream: TMemoryStream);
var
  Bytes: TAByte;
  Size: integer;
begin
  Bytes:= Decode64(S);
  Size:= Length(Bytes);
  MStream.SetSize(Size);
  Move(Bytes[0], MStream.Memory^, Size);
  SetLength(Bytes,0);
end;


Saludos.
Responder Con Cita
  #13  
Antiguo 15-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
Muchas gracias por el aporte amigos.
Les dejo una forma que llegué con NetEncoding, la cual me resultó bastante facil(por decir porq me costo además que nunca había hecho esto).
También aparece en el código el envío al servidor Node, el cual guarda en la base de datos Mysql en un campo Longblob.
Hasta ahí me funcionó impecable, para decodificar la imagen nuevamente también lo hice con netencoding.
En la decodificación lo que me está faltando es procesar la consulta que hago al servidor, la cual el servidor devuelve la consulta en formato json y el campo de la imagen en formato buffer, como hago para convertir el buffer a base64, estoy viendo para que el servidor lo devuelva, sino lo tengo que procesar en Delphi.

Código Delphi [-]
procedure TForm1.Button4Click(Sender: TObject);
var
SS: TStringStream;
V, resultado: string;
  enco : TNetEncoding;
  lparamlist: TStringList;
  cadena, res: string;
  obj : tjsonobject;

begin
enco :=  TNetEncoding.Create;
  SS := TStringStream.Create('');
  image1.Bitmap.LoadFromFile('c:\img\imgextintor\2.jpg');
  Image1.Bitmap.SaveToStream(SS);
  V := SS.DataString;
  resultado := enco.Base64.Encode(V);
  memo1.lines.add(resultado);
  memo1.Lines.SaveToFile('c:\memo.txt');
  lparamlist := TStringList.Create;
  lparamlist.Add('idImg=5');
  lparamlist.Add('imagen=' + resultado);

  res := http.Post('http://localhost:3000/subiFoto', lparamlist);
 showmessage(res);
  lparamlist.Free;

end;
------------------------------------
decodifico

Código Delphi [-]
  V := enco.Base64.Decode(resultado);
  SS := TStringStream.Create(V);
  Image2.Bitmap.LoadFromStream(SS);
Responder Con Cita
  #14  
Antiguo 16-03-2016
D1360666 D1360666 is offline
Miembro
 
Registrado: mar 2008
Posts: 53
Poder: 17
D1360666 Va por buen camino
En el caso de enviar la foto sin codificarla a base64 utilizando Indy con el componente TIDHTTP, alguién tiene alguna idea de como sería el código, para enviar el jpg a un webservice??

He pasado texto, con http.post(url, paramlist)

Donde paramlist es una variable TStringList cargada con los campos que se pasan como parámetro.

Ya aprovecho.
Cuando pude codificar la imagen a base64, se la envío al servidor y él, la guarda en mysql en un campo longblob exitosamente.
En el caso de consultar la imagen, el servidor me devuelve el valor longblob como tipo BUFFER.
Como hago para decodificar el tipo BUFFER.

Como verán el subir imágenes nunca lo había hecho y estoy buscando la mejor forma o mejor dicho la forma correcta de poder tratarlas.

Este es el resultado de la consulta al servidor
https://drive.google.com/open?id=0Bw...zN2RHgxN0xDVHc
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 15:22:56.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi