Ir al contenido


Foto

Cargar imagen codificado en base64 desde JSON


  • Por favor identifícate para responder
5 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 19 diciembre 2016 - 11:58

Amigos, tengo el siguiente problema tengo imagenes guardados en una base de datos mysql en campo blob, esa imagen la codifico en base64 para devolverlo a traves de JSON, en delphi decodifico esa información y lo guardo en un stream para cargarlo a traves de TBitmap.LoadFromStream pero me da errores, aqui el codigo:


delphi
  1. function DecodeImgFromBase64(AStr: WideString): TStream;
  2. var AStream: TStream;
  3. begin
  4. AStream := TStream.Create;
  5. TBlobField(DecodeBase64(AStr)).SaveToStream(AStream);
  6. AStream.Position := 0;
  7. Result := AStream;
  8. end;

Hay una mejor forma de lograr eso?.

 

Saludos.


  • 0

#2 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 19 diciembre 2016 - 01:12

Que errores?


  • 0

#3 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 19 diciembre 2016 - 01:31

Deberias abstraerte de la nocion de que tu base64 esta en un campo de una base de datos. A fin de cuentas, no cambia nada, tenes siempre un TStream

 

Existen que yo sepa tres alternativas que vienen de fabrica con Delphi para trabajar con Base64:


delphi
  1. uses
  2. System.SysUtils,
  3. System.Classes,
  4. System.NetEncoding,
  5. Soap.EncdDecd,
  6. IdCoderMIME,
  7. Data.DB;
  8.  
  9. // usando System.NetEncoding
  10. function DecodeStreamNetEncoding(BlobStream: TStream): TStream;
  11. var
  12. Decoder: TNetEncoding;
  13. begin
  14. Result := TMemoryStream.Create;
  15. BlobStream.Position := 0;
  16. Decoder := TNetEncoding.Base64;
  17. try
  18. Decoder.Decode(BlobStream, Result);
  19. finally
  20. Decoder.Free;
  21. end;
  22. end;
  23.  
  24. // usando Indy (unidad IdCoderMIME)
  25. function DecodeStreamIndy(BlobStream: TStream): TStream;
  26. var
  27. BlobStringSteram: TStringStream;
  28. Base64: string;
  29. begin
  30. BlobStringSteram := TStringStream.Create;
  31. try
  32. BlobStream.Position := 0;
  33. BlobStringSteram.CopyFrom(BlobStream, BlobStream.Size);
  34. Base64 := TIdDecoderMIME.DecodeString(BlobStringSteram.DataString);
  35. Result := TStringStream.Create(Base64);
  36. finally
  37. BlobStringSteram.Free;
  38. end;
  39. end;
  40.  
  41. // usando Soap.EncdDecd
  42. function DecodeStreamEncdDecd(BlobStream: TStream): TStream;
  43. var
  44. Base64: TBytes;
  45. BlobStringSteram: TStringStream;
  46. begin
  47. BlobStringSteram := TStringStream.Create;
  48. try
  49. BlobStream.Position := 0;
  50. BlobStringSteram.CopyFrom(BlobStream, BlobStream.Size);
  51. Base64 := DecodeBase64(BlobStringSteram.DataString);
  52. Result := TStringStream.Create(Base64);
  53. finally
  54. BlobStringSteram.Free;
  55. end;
  56. end;

Para obtener el blob como stream de un determinado campo podes usar una sencilla funcion:


delphi
  1. function GetBlobStream(Field: TBlobField): TStream;
  2. begin
  3. Result := TMemoryStream.Create;
  4. Field.SaveToStream(Result);
  5. end;

La otra posibilidad es que tengas problemas con el Encoding. El tipo de datos "string" a secas no existe mas. Lo que tenes es un arreglo de caracteres que estan codificados usando un Encoding (UTF8, ANSI, ASCII,etc). Si no especificas el Encoding adecuado, podes tener perdida de informacion y eso te genera errores al convertir desde/hacia Base64

 

Para ese punto si te va a interesar el collate del campo en la BD y tambien como lo tratas en el codigo. Por que usas WideStrnig en tu funcion?


Editado por Agustin Ortu, 19 diciembre 2016 - 01:35 .

  • 0

#4 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 19 diciembre 2016 - 05:16

Gracias Agustín, lo de Widestrin es un error, en realidad es AnsiString, porque la función DecodeBase64 tiene como parámetros ese tipo de datos, en realidad la API REST está hecho en PHP y JSON no acepta datos binarios (AL menos desconozco lo contrario), por eso debo codificarlo como base64 y en delphi debo decodificarlo, se supone debo convertir esos Bytes a Stream y es lo que no he logrardo conseguir.


  • 0

#5 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 19 diciembre 2016 - 05:24

Yo te recomiendo usar siempre string. El compilador solo realiza la conversion UnicodeString <--> AnsiString. Por lo general emite un warning avisandote de que la conversion es implicita pero que existe.

 

Que errores te da el codigo que usaste?


  • 0

#6 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 19 diciembre 2016 - 05:53

Pues del tipo de Exception con valores hexagesimales que ahora mismo no lo tengo a mano, pero ahora resolví eso de otra manera, ya que utilizo Slim Framework para la API REST, las imágenes son un poco tedioso, lo que hice fue crear una carpeta de imagenes fuera de slim y guardar las imágenes ahí, con la ayuda de un Helper a la clase TBitmap, introduje un procedimiento del tipo Tipo LoadFormURL y voilá!, sólo queda pelearme cómo subir imágenes desde el móvil.

 

FMX.DevGear.HelperClass

 

Saludos.


  • 0