Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Leer imagen desde una base de datos en el servidor (https://www.clubdelphi.com/foros/showthread.php?t=94059)

jrojasmcfia 10-07-2019 22:27:11

Leer imagen desde una base de datos en el servidor
 
Hola con el siguiente código he logrado cargar una imagen a la app creada en windows desde una dirección http.
ejemplo url:=http://mipagina/imagenes/logo,jpg, sin embargo necesito hacer lo mismo pero con imagenes almacenandas en la base de datos del servidor en este caso es una base de datos MySql y el campo es tipo blob. Supongo que la url debe apuntar a un php que devuelva la imagen, en php ya puedo hacer la consulta de la imagen pero que tiene que devolver para que el componente indy lo entienda. Les agradecerìa un ejemplo de como se puede hacer esto, saludos!



Código Delphi [-]
var
imagenstream : TStringSTream;

  ImgStream := TMemoryStream.Create;
  idHttp1 := TIdHTTP.Create(nil);
  idhttp1.get(url,ImgStream);
  ImgStream.Position := 0;
  image1.Bitmap.LoadFromStream(ImgStream);
  ImgStream.Free;

bucanero 11-07-2019 10:22:49

hola

Por lo que comentas no dejas claro si lo que quieres es leer directamente la imagen conectándote directamente al servidor y procesar la imagen allí almacenada en el campo blob, que se plantearía con componentes de base de datos

Cita:

Empezado por jrojasmcfia (Mensaje 532741)
sin embargo necesito hacer lo mismo pero con imagenes almacenandas en la base de datos del servidor en este caso es una base de datos MySql y el campo es tipo blob.

O prentendes acceder a una URL de tu servidor que sera la encargada de servirte la imagen,
Cita:

Empezado por jrojasmcfia (Mensaje 532741)
Supongo que la url debe apuntar a un php que devuelva la imagen, en php ya puedo hacer la consulta de la imagen pero que tiene que devolver para que el componente indy lo entienda.

Si el caso es el de este segundo punto, leerlo desde una URL determinada, lo único que debes de hacer en tu servidor de PHP es mostrar la imagen como un JPG normal (que se pueda visualizar en un navegador).
Y aquí un enlace de como hacerlo:
mostrar-una-imagen-desde-blob-mysql-usando-php

Y en la parte de delphi, ya es totalmente independiente la forma en que esta almacenada en el servidor web, solamente se trata de leer una imagen almacenada en una URL.

Uno de los problemas que puedes tener es que la imagen, bien sea la recibida tanto desde el servidor como la almacenada en la BBDD, no sea un BMP que es lo que trabaja delphi de forma nativa, por lo que tienes que hacer procesos de conversión de formato

Aquí te dejo un código de ejemplo para cambiar de formato la imagen, y el ejemplo completo que lee una imagen desde una URL y determina el tipo de imagen por los caracteres de su cabecera

Código Delphi [-]
uses
  Jpeg, pngimage, GIFImg;

procedure DetectImage(FS: TStream; BM: TBitmap); overload;
/// Este procedimiento detecta el tipo de imagen (BMP, PNG, JPG, GIF) y la carga en formato BMP
var
  FirstBytes: AnsiString;
  Graphic: TGraphic;
begin
  try
    Graphic := nil;

    SetLength(FirstBytes, 8);
    FS.Position := 0;
    FS.Read(FirstBytes[1], 8);
    if Copy(FirstBytes, 1, 2) = 'BM' then
      Graphic := TBitmap.Create
    else if FirstBytes = #137'PNG'#13#10#26#10 then
      Graphic := TPngImage.Create
    else if Copy(FirstBytes, 1, 3) = 'GIF' then
      Graphic := TGIFImage.Create
    else if Copy(FirstBytes, 1, 2) = #$FF#$D8 then
      Graphic := TJPEGImage.Create;

    if Assigned(Graphic) then
    try
      FS.Seek(0, soFromBeginning);
      Graphic.LoadFromStream(FS);
      BM.Assign(Graphic);
    except
    end;
  finally
    FreeAndNil(Graphic);
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  ImgStream: TMemoryStream;
  url: string;
begin
  // Una imagen de ejemplo cualquiera
  url := 'https://live.staticflickr.com/2724/4362845813_d550daa427_z.jpg';
  try
    ImgStream := nil;
    ImgStream := TMemoryStream.Create;
    idhttp1.get(url, ImgStream);
    DetectImage(ImgStream, image1.Picture.Bitmap);
  finally
    ImgStream.Free;
  end;
end;

jrojasmcfia 11-07-2019 16:02:12

Hola Bucanero gracias por tu respuesta, voy a realizar algunas pruebas de lo que me envias.
me parece que esta es la clave en el php, ahora bien no se si delphi podrà capturar la imagen de este PHP pues leyendo el ejemplo veo que es para que una etiqueta img de html la pueda mostrar, ese no es mi caso la idea es que delphi la capture y la muestre en la app que diseñe para Android.


Código PHP:

header("Content-Type: $mime");
// Muestra la imagen
echo $imagen


bucanero 11-07-2019 18:11:30

Con el ejemplo anterior, que incluye el método de detección del tipo de fichero en función de su cabecera, no deberías de tener problemas bien le envíes las MIME o no se las envíes, puesto que las va a detectar de forma automática.

Yo acabo de hacer una prueba con este ejemplo simple de PHP en la parte del servidor y me ha funcionado tanto enviando el HEADER con el tipo de fichero, donde el navegador puede visualizar la imagen correctamente, como sin enviar el HEADER donde el navegador ya solo muestra un montón de caracteres raros, puesto que no sabe que tipo de datos son los que esta recibiendo

Código PHP:

<?php
  $SQL 
'
    SELECT `image` 
    FROM `images` 
    WHERE `id` = 1
  '
;
  
$query tep_db_query($SQL);
  
  if ( 
$data tep_db_fetch_array($query) ) {
    
header("Content-type: image/jpg");
    echo 
$data['image'];   
  }
?>


jrojasmcfia 15-07-2019 19:03:32

1 Archivos Adjunto(s)
Hola , gracias por las respuestas pero en realidad lo que ocupo es leer una imagen almacenada en una Base de data mysql y cargarla en una aplicacion en Delphi, lo que son archivos tipo imagen como los ejemplos que me pusieron si los logro hacer, sin embargo al tratar de extraer la image de una base datos no la logro pasar bien a la app, en un principio mi idea es pasarla via PHP mediante JSON y luego capturar el string con HTTP de los componentes indy adjunto tanto mi php como el codigo en delphi para hacer esto.El inconveniente que se me presenta es que aunque logro leer del JSON los valores nregistro y fecha el campo imagen me da error, en el código indico con un comentario el fragmento de código que me da error, si pudieran ayudarme con esto se los agradezco mucho, en realidad si lograra leer la imagen luego la decodificaria a tipo imagen y listo.
Adjunto tambien la respuesta del JSON en pdf




Código PHP:


$query 
"SELECT nregistro,Fecha,Imagen FROM resgistrodatos WHERE nregistro = 1 order by Fecha";

if (!
$resultado mysqli_query($link,$query)) die();

   
$rawdata['imagenes'] = array();
   
//guardamos en un array multidimensional todos los datos de la consulta
   
$i=0;
   

 
while(
$row mysqli_fetch_array($resultado))
   {
    
array_push($rawdata['imagenes'], array(
     
'fecha' => $row['fecha'],
     
'nregistro' => $row['nregistro'],
     
'photo' => base64_encode($row['Imagen'])
    ));
   }

mysqli_close($link);

header('Content-type: application/json');

echo 
json_encode($rawdata); 


Código Delphi [-]

procedure TForm1.Button1Click(Sender: TObject);
var
JSonValue:TJSonValue;
Branch,ss:string;
st:ansistring;

imagen:ansistring;

strm:TMemoryStream;
imagenstream : TStringSTream;
ImgStream: TMemoryStream;
JSonObject:TJSonObject;


begin
ImgStream := TMemoryStream.Create;

  idHttp1 := TIdHTTP.Create(nil);
  idhttp1.get('http://mipagina/develveimagen.php',ImgStream);
  ImgStream.Position := 0;
  st := MemoryStreamToString(ImgStream);

   JSonObject := TJSonObject.Create;
   JsonValue:=JSonObject.ParseJSONValue(st);
   JsonValue:=(JsonValue as TJSONObject).Get('imagenes').JSONValue;


   if (JSONValue is TJSONArray) then
      nresgistro:= ((JSONValue as TJSONArray).Items[0] as TJSonObject).Get('nregistro').JSONValue.Value;
      fecha  :=  ((JSONValue as TJSONArray).Items[0] as TJSonObject).Get('fecha').JSONValue.Value;

     //ESte me esta dando error

      imagen  :=  ((JSONValue as TJSONArray).Items[0] as TJSonObject).get('imagen').JSONValue.Value;

end;

bucanero 16-07-2019 11:00:07

En principio en tu código de PHP lo veo correcto, aunque con esa estructura de datos aparecen varias cuestiones que debes de solventar en la parte de DELPHI:

1.- Los datos los traes encapsulados en un objeto JSON, el cual debes primeramente poder leer.
Para este punto puedes utilizar un generador de classes de JSON a DELPHI, yo en particular para esta prueba he utilizado https://jsontodelphi.com/, donde metes la estructura del JSON y te devuelve una unidad con la clase generada, haciendo prácticamente transparente el proceso de conversión de datos.

La estructura de JSON que parece que tienes es similar a esta:
Código:

{"imagenes":[
{"fecha":"2019-07-16 10:34:32","nregistro":"1","photo":"datos_imagen_1"},
{"fecha":"2019-07-16 10:34:32","nregistro":"2","photo":"datos_imagen_2"},
...
{"fecha":"2019-07-16 10:34:32","nregistro":"2","photo":"datos_imagen_n"}
]}

2.- Los datos de la imagen los traes codificados en BASE64 por lo que después de leerlos debes de descodificarlos. Aquí puedes utilizar las herramientas que proporciona DELPHI en particular en la unidad System.NetEncoding


Y con este código deberías de poder leer las imágenes sin mayor problema

Código Delphi [-]
procedure LoadStringImageEncoded(Bitmap: TBitmap; const AImageData: string);
var
  ImgStream: TStringStream;
  img2: TMemoryStream;
begin
  try
      // Este es el stream de salida donde se van almacenar los datos ya descodificados
    img2 := TMemoryStream.Create;
    try
        //cargo en un Stream los datos codificados en BASE64
      ImgStream := TStringStream.create(AImageData);
        // decodificar los datos recibidos
      TNetEncoding.Base64.Decode(ImgStream, img2);
    finally
      ImgStream.free;
    end;
      // se carga la imagen en un componente TImage
    DetectImage(img2, Bitmap);
  finally
    img2.free;
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  url: string;
begin
  // Una imagen de ejemplo cualquiera
  url := 'http://localhost/clubdelphi/';
  try
    // RootClass es la clase generada que se encarga de leer los datos JSON
    RootClass := TRootClass.FromJsonString(idhttp1.get(url));
    if (Length(RootClass.imagenes) > 0) then
      // La imagen viene codificada en base64, y con este proceso se descodifica
      LoadStringImageEncoded(image1.Picture.Bitmap, RootClass.imagenes[0].photo);
  finally
    FreeAndNil(RootClass);
  end;
end;


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

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