Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-02-2016
Ramsay Ramsay is offline
Miembro
NULL
 
Registrado: ene 2016
Posts: 104
Poder: 9
Ramsay Va por buen camino
Leer imagen y convertir su contenido a base64

Hola , necesito leer una imagen para convertir su contenido a base64 y usarlos en html facilmente , pero no encuentro referencias sobre como leer la imagen , ¿ como podria hacer esto ?
Responder Con Cita
  #2  
Antiguo 10-02-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
Una alternativa es usando los componentes Indy:

Código Delphi [-]
unit Unit2;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  StdCtrls,
  ExtCtrls,
  IdBaseComponent,
  IdCoder,
  IdCoder3to4,
  IdCoderMIME;

type
  TForm2 = class(TForm)
    IdEncoderMIME1: TIdEncoderMIME;
    imLoad: TImage;
    OpenDialog1: TOpenDialog;
    imBase64: TImage;
    btnLoad: TButton;
    btnToBase64: TButton;
    IdDecoderMIME1: TIdDecoderMIME;
    procedure btnLoadClick(Sender: TObject);
    procedure btnToBase64Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.btnLoadClick(Sender: TObject);
begin
  if not OpenDialog1.Execute then
    Exit;

  imLoad.Picture.LoadFromFile(OpenDialog1.FileName);
end;

procedure TForm2.btnToBase64Click(Sender: TObject);
var
  AImageStream: TMemoryStream;
  AStringStream: TStringStream;
  ABase64, DecodedBase64: string;
begin
  AImageStream := TMemoryStream.Create;
  try
    imLoad.Picture.Graphic.SaveToStream(AImageStream);
    AImageStream.Position := 0;
    ABase64 := IdEncoderMIME1.Encode(AImageStream);
  finally
    AImageStream.Free;
  end;

  DecodedBase64 := IdDecoderMIME1.DecodeString(ABase64);
  AStringStream := TStringStream.Create(DecodedBase64);
  try
    AStringStream.Position := 0;
    imBase64.Picture.Bitmap.LoadFromStream(AStringStream);
  finally
    AStringStream.Free;
  end;
end;

end.
Responder Con Cita
  #3  
Antiguo 10-02-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
Esta es otra forma similar a la anterior, pero usando metodos estaticos (de clase)

Código Delphi [-]
procedure TForm2.btnToBase64Click(Sender: TObject);
var
  AStringStream: TStringStream;
  ABase64, DecodedBase64: string;
begin
  AStringStream := TStringStream.Create;
  try
    imLoad.Picture.Graphic.SaveToStream(AStringStream);
    AStringStream.Position := 0;
    ABase64 := TIdEncoderMIME.EncodeString(AStringStream.DataString);
  finally
    AStringStream.Free;
  end;

  DecodedBase64 := TIdDecoderMIME.DecodeString(ABase64);
  AStringStream := TStringStream.Create(DecodedBase64);
  try
    AStringStream.Position := 0;
    imBase64.Picture.Bitmap.LoadFromStream(AStringStream);
  finally
    AStringStream.Free;
  end;
end;
Responder Con Cita
  #4  
Antiguo 10-02-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
Y la ultima variante es utilizando las funciones definidas en la unidad Soap.EncdDecd:

Código Delphi [-]
var
  AMemStream: TMemoryStream;
  AStreamBase64, ADecodedStream: TStringStream;
  ABase64, DecodedBase64: string;
begin
  AMemStream := TMemoryStream.Create;
  AStreamBase64 := TStringStream.Create;
  try
    imLoad.Picture.Bitmap.SaveToStream(AMemStream);
    AMemStream.Position := 0;
    EncodeStream(AMemStream, AStreamBase64);
    AStreamBase64.Position := 0;
    ABase64 := AStreamBase64.DataString;
  finally
    AStreamBase64.Free;
  end;

  DecodedBase64 := DecodeString(ABase64);
  ADecodedStream := TStringStream.Create(DecodedBase64);
  try
    ADecodedStream.Position := 0;
    imBase64.Picture.Bitmap.LoadFromStream(ADecodedStream);
  finally
    ADecodedStream.Free;
  end;

Esta ultima fue la que logro replicar la imagen exactamente a como estaba antes; curioso que los componentes Indy tengan alguna falla

Las pruebas las hice con formato BMP
Responder Con Cita
  #5  
Antiguo 10-02-2016
Avatar de ElKurgan
[ElKurgan] ElKurgan is offline
Miembro Premium
 
Registrado: nov 2005
Posts: 1.231
Poder: 20
ElKurgan Va camino a la fama
¿En que Delphi estás probando?

Yo estoy haciendo la prueba de la función de Soap en Delphi XE7 y no decodifica bien, me devuelve una excepción "EEncodingError": No mapping for the Unicode character exists in the target multi-byte code page"

No tengo ni idea de porqué pasa esto...
Responder Con Cita
  #6  
Antiguo 10-02-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
Los 3 ejemplos Delphi 2010

Cual te da error? El componente Indy te permite especificar un TEncoding que creo que es lo que te esta fallando
Responder Con Cita
  #7  
Antiguo 10-02-2016
Avatar de ElKurgan
[ElKurgan] ElKurgan is offline
Miembro Premium
 
Registrado: nov 2005
Posts: 1.231
Poder: 20
ElKurgan Va camino a la fama
Los componentes Indy no me dan error, eso si, no decodifican bien. Es justamente la línea siguiente


Código Delphi [-]
DecodedBase64 := DecodeString(ABase64);

¿Tendrá que ver con la configuración del equipo y la página de códigos?

En fin, gracias y un saludo
Responder Con Cita
  #8  
Antiguo 10-02-2016
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Yo utilizo la API para esos fines:

Código Delphi [-]
const
  CRYPT_STRING_BASE64 = 1;

function CryptBinaryToString(pbBinary: PByte; cbBinary: DWORD; dwFlags: DWORD;
  pszString: PChar; var pcchString: DWORD): BOOL; stdcall;
  external 'Crypt32.dll' name 'CryptBinaryToStringA';

function CryptStringToBinary(pszString: PChar; cchString: DWORD; dwFlags: DWORD;
  pbBinary: PByte; var pcbBinary: DWORD; pdwSkip: PDWORD;
  pdwFlags: PDWORD): BOOL; stdcall;
  external 'Crypt32.dll' name 'CryptStringToBinaryA';

//---------------------------------------------------------------------------
// Codifica un TNMemoryStrean a cadena Encode64
function StreamToStrB64(MStream: TMemoryStream; var Str: String): boolean;
var
  Size: DWORD;
begin
  Result:= CryptBinaryToString(MStream.Memory, MStream.Size, CRYPT_STRING_BASE64, 0 , Size);
  if Result then
  begin
    SetLength(Str, Size);
    Result:= CryptBinaryToString(MStream.Memory, MStream.Size, CRYPT_STRING_BASE64, @Str[1], Size);
  end;
end;

//---------------------------------------------------------------------------
// Decodifica una cadena Encode64 a su binario original en un TMemoryStream
function StrB64ToStream(var Str: String; MStream: TMemoryStream): boolean;
var
  Size: DWORD;
begin
  Result:= CryptStringToBinary(@Str[1], Length(Str), CRYPT_STRING_BASE64, 0, Size, nil, nil);
  if Result then
  begin
    MStream.SetSize(Size);
    Result:= CryptStringToBinary(@Str[1], Length(Str), CRYPT_STRING_BASE64, MStream.Memory, Size, nil, nil);
  end;
end;

Para el tema en cuestión, el uso sería:

Código Delphi [-]
var
  MStream: TMemoryStream;
  S: String;  // Aquí tendremos la cadena BASE64 de la Imagen
begin
  MStream:= TMemoryStream.Create;
  Image1.Picture.Bitmap.SaveToStream(MStream);
  StreamToStrB64(MStream, S);
  MStream.Free;
end;

Por si interesa, aquí mostré un ejemplo de como leer una imagen codificada en BASE64 sin conocer el tipo de la misma usando GDI+.


Saludos,
Responder Con Cita
  #9  
Antiguo 10-02-2016
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Una aclaración:

Hay que tener en cuenta que la API CryptBinaryToString, cuando la usamos para codificar en Base64 (CRYPT_STRING_BASE64) codifica el buffer pasado completo y le añade un retorno de carro (13) y otro de línea (10) y un nulo final. Cuando se encripta una cadena PCHAR, el cero final también lo encripta.

No he probado con Inddy, pero el detalle que describo puede ocasionar errores aparentes en el cifrado-descifrado.


Saludos.
Responder Con Cita
  #10  
Antiguo 10-02-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
Excelente como siempre escafandra

Otra forma de leer *cualquier tipo de imagen* sin conocer el formato se expone aca Vcl.BlobImageLoader

Si bien esta enfocado a leer campos de una BD (campos blob) adaptarlo para que reciba un string o TStream deberia ser muy sencillo

Toda la magia de averiguar el formato de la imagen es obra del gran Chris Rolliston

Saludos
Responder Con Cita
  #11  
Antiguo 11-02-2016
Avatar de ElKurgan
[ElKurgan] ElKurgan is offline
Miembro Premium
 
Registrado: nov 2005
Posts: 1.231
Poder: 20
ElKurgan Va camino a la fama
O.K., muchas gracias por tus siempre interesantes aporte, Escafandra.

Cuando pueda lo pruebo y te comento.

De todas formas, en XE7 he encontrado algunos "fallitos" que, oh maravilla, se han corregido en la versión XE8, es decir, a pagar si quieres tener esos detalles arreglados.

Gracias y un saludo
Responder Con Cita
  #12  
Antiguo 11-02-2016
Avatar de ElKurgan
[ElKurgan] ElKurgan is offline
Miembro Premium
 
Registrado: nov 2005
Posts: 1.231
Poder: 20
ElKurgan Va camino a la fama
Thumbs up

Con las llamadas al API funciona perfecto.

Gracias de nuevo.
Responder Con Cita
  #13  
Antiguo 11-02-2016
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por ElKurgan Ver Mensaje
De todas formas, en XE7 he encontrado algunos "fallitos" que, oh maravilla, se han corregido en la versión XE8, es decir, a pagar si quieres tener esos detalles arreglados.
Pues los fallitos en temas perfectamente estandarizados no son otra cosa que un "defecto de fábrica" sujeto a la garantía del fabricante, solucionarlos no son una mejora, sino la garantía de un producto fiable. Si has de pagar por lo que debería ser un derecho, mejor no comprar el producto.

Saludos.
Responder Con Cita
  #14  
Antiguo 18-05-2018
tatifuentesvasq tatifuentesvasq is offline
Registrado
NULL
 
Registrado: mar 2014
Posts: 3
Poder: 0
tatifuentesvasq Va por buen camino
y decodificar unos bytes a una imagen bmp

Cita:
Empezado por AgustinOrtu Ver Mensaje
Y la ultima variante es utilizando las funciones definidas en la unidad Soap.EncdDecd:

Código Delphi [-]
var
  AMemStream: TMemoryStream;
  AStreamBase64, ADecodedStream: TStringStream;
  ABase64, DecodedBase64: string;
begin
  AMemStream := TMemoryStream.Create;
  AStreamBase64 := TStringStream.Create;
  try
    imLoad.Picture.Bitmap.SaveToStream(AMemStream);
    AMemStream.Position := 0;
    EncodeStream(AMemStream, AStreamBase64);
    AStreamBase64.Position := 0;
    ABase64 := AStreamBase64.DataString;
  finally
    AStreamBase64.Free;
  end;

  DecodedBase64 := DecodeString(ABase64);
  ADecodedStream := TStringStream.Create(DecodedBase64);
  try
    ADecodedStream.Position := 0;
    imBase64.Picture.Bitmap.LoadFromStream(ADecodedStream);
  finally
    ADecodedStream.Free;
  end;

Esta ultima fue la que logro replicar la imagen exactamente a como estaba antes; curioso que los componentes Indy tengan alguna falla

Las pruebas las hice con formato BMP


PODRIAS POR FAVOR EXPLICARME UN POCO, QUE YA ME HICE BOLAS... por lo que entiendo hay decodifican la imagen par volverla un string... (estoy mal?), y yo lo que tengo es un archivo extenso donde tengo que decodificar para convertir a imagen, podrian ayudarme?
Responder Con Cita
  #15  
Antiguo 18-05-2018
tatifuentesvasq tatifuentesvasq is offline
Registrado
NULL
 
Registrado: mar 2014
Posts: 3
Poder: 0
tatifuentesvasq Va por buen camino
convertir imagen de base 64 a imagen .bmp




PODRIAS POR FAVOR EXPLICARME UN POCO, QUE YA ME HICE BOLAS... por lo que entiendo hay decodificas una imagen para replicarla... (estoy mal?), y yo lo que tengo es un archivo extenso .txt que debo decodificar para convertir a imagen, podrian ayudarme?
Responder Con Cita
  #16  
Antiguo 18-05-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.011
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por tatifuentesvasq Ver Mensaje
...
Por favor, lee nuestra guia de estilo, gracias... y bienvenido a clubdelphi
Responder Con Cita
  #17  
Antiguo 18-05-2018
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por tatifuentesvasq Ver Mensaje



PODRIAS POR FAVOR EXPLICARME UN POCO, QUE YA ME HICE BOLAS... por lo que entiendo hay decodificas una imagen para replicarla... (estoy mal?), y yo lo que tengo es un archivo extenso .txt que debo decodificar para convertir a imagen, podrian ayudarme?
Si tu archivo txt es encode64, puedes usar la función StrB64ToStream descrita en la respuesta 8


Saludos.
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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Mostrar imagen que viene en Base64 jars Gráficos 7 25-06-2012 10:42:57
Como puedo convertir una imagen a una imagen semitransparente? antonio302050 Gráficos 0 27-03-2010 18:01:48
leer el contenido de un archivo txt ingmichel Varios 6 11-07-2008 16:27:17
Leer Contenido URL adonias Varios 3 14-09-2007 18:12:18
Leer contenido de cd's rruffino Varios 3 09-01-2005 01:56:54


La franja horaria es GMT +2. Ahora son las 09:20:43.


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