PDA

Ver la Versión Completa : Pegar imagen desde el Portapapeles (Clipboard)


gluglu
12-06-2008, 16:53:03
Hola amig@s !

Ya estoy deseperado y no sé como seguir. He buscado de todo pero no consigo encontrar la solución, por eso tengo que acudir a vuestra ayuda.

Trato de copiar una imagen del Clipboard a un TImage. Todo funciona perfecto si he copiado previamente una imagen al Clipboard por ejemplo desde una página web.

Pero lo raro es que si abro el Explorador de Windows, elijo una imagen JPG o BMP y en el mismo explorador de windows le doy a copiar al clipboard ese fichero de tipo imagen, después el Delphi no es capaz de reconocer el formato y no sé por qué.

He probado con todas estas opciones, tanto con imágenes JPG como con BMP

Image1.Picture.Bitmap.LoadFromClipboardFormat(CF_BITMAP, ClipBoard.GetAsHandle(CF_BITMAP), 0);

Image1.Picture.LoadFromClipBoardFormat(cf_BitMap, ClipBoard.GetAsHandle(cf_Bitmap), 0);

Image1.Picture.Bitmap.Assign(Clipboard);

Gracias por vuestra ayuda. ;)

jhonny
12-06-2008, 17:04:33
A ver si de pronto le pego donde es... ¿Ya añadiste la unidad jpeg en el uses? :)

gluglu
12-06-2008, 17:10:43
Si, si funciona todo a la perfección, incluso grabando en mi base de datos. Tanto con imágenes JPG como BMP. Lo tengo todo hecho.

El problema es si lo que quiero hacer es abrir el explorador, elegir una imagen (JPG o BMP), elegir copiar, y después pegar esa imagen elegida en el explorador al TImage. Ahí es cuando me da error y me dice que el formato no es soportado. He intentado de todas las maneras averiguar el formato que es y no lo consigo.

Pregunto yo .... será que al copiar desde el explorador al portapapeles, lo que se está copiando es algún objeto del tipo 'File' o algo así, en vez de la propia imagen BMP o JPG ?? :confused:

egostar
12-06-2008, 17:16:13
Si, si funciona todo a la perfección, incluso grabando en mi base de datos. Tanto con imágenes JPG como BMP. Lo tengo todo hecho.

El problema es si lo que quiero hacer es abrir el explorador, elegir una imagen (JPG o BMP), elegir copiar, y después pegar esa imagen elegida en el explorador al TImage. Ahí es cuando me da error y me dice que el formato no es soportado. He intentado de todas las maneras averiguar el formato que es y no lo consigo.

Pregunto yo .... será que al copiar desde el explorador al portapapeles, lo que se está copiando es algún objeto del tipo 'File' o algo así, en vez de la propia imagen BMP o JPG ?? :confused:

Si lo que estas haciendo es Alt+Print Screen, lo que te guarda es un archivo al portapapeles del tipo

nombre.jpg.tmp

Habria que ver de que manera quitarle la extension tmp

Salud OS

gluglu
12-06-2008, 17:22:10
Comento de nuevo que todo me funciona perfectamente si lo que pego al TImage es una imagen que previamente he seleccionado por ejemplo en una página web.

También mi funciona si con un OpenDialog grabo la imagen seleccionada a la base de datos y después la muestro en el TImage.

Lo que pensaba que sería además una operación de lo más normal, era abrir el explorador de windows, seleccionar cualquier imagen JPG o BMP que tenga en mi disco, elija 'copiar' al portapapeles, y después vuelvo a mi programa, y en el TImage le doy 'pegar'.

Si la imagen la seleccioné en una web funciona. Si el fichero de imagen BMP o JPG lo seleccioné en el Explorador de Windows, no me funciona. Me salta el error diciendo que el formato no es soportado.

Es que el contenido del clipboard no es realmente una imagen si he seleccionado un fichero BMP o JPG en el explorador de windows ?

gluglu
12-06-2008, 17:28:19
Estoy investigando.

Creo que queda claro que cuando elijo algo en el explorador de windows y lo copio al portapapeles, no estoy copiando un elemento del tipo BMP o JPG.

Acabo de encontrar esto para averiguar los nombres de los ficheros que haya seleccionado en el explorador y haya copiado al portapapeles. Creo que los tiros van por ahí.

var
f: THandle;
buffer: Array [0..MAX_PATH] of Char;
i, numFiles: Integer;
begin
Clipboard.Open;
try
f:= Clipboard.GetAsHandle( CF_HDROP ) ;
If f <> 0 Then Begin
numFiles := DragQueryFile( f, $FFFFFFFF, nil, 0 ) ;
memo1.Clear;
for i:= 0 to numfiles - 1 do begin
buffer[0] := #0;
DragQueryFile( f, i, buffer, sizeof(buffer)) ;
memo1.lines.add( buffer ) ;
end;
end;
finally
Clipboard.close;
end;
end;

gluglu
12-06-2008, 17:37:12
Ya voy encaminando la cosa !

Claro ! :rolleyes: Lo que estoy copiando al portapapeles desde el explorador de windows, son uno o varios 'nombres' de ficheros. Lo que tengo es que analizar esos nombres y después tratar los ficheros correspondientes para incorporarlos al TImage.

Cuando tenga la solución definitiva, la pondré aquí. ;)

gluglu
12-06-2008, 20:59:20
Aquí va la solución.

Sirve para copiar pegar desde el Portapapeles un fichero (por ejemplo seleccionado desde el explorador de WIndows) que contenga una imagen tipo JPG o BMP.


...
var
f : TFileStream;
Jpg : TJpegImage;
Hand : THandle;
Buffer : Array [0..MAX_PATH] of Char;
numFiles : Integer;
File_Name : String;
Jpg_Bmp : String;
BitMap : TBitMap;
ImageAux : TImage;

begin

ImageAux := TImage.Create(Self);

if Clipboard.HasFormat(CF_HDROP) then begin

Clipboard.Open;
try
Hand := Clipboard.GetAsHandle(CF_HDROP);
If Hand <> 0 then begin
numFiles := DragQueryFile(Hand, $FFFFFFFF, nil, 0) ;
if numFiles > 1 then begin
Clipboard.Close;
ImageAux.Free;
MessageError('El Portapapeles contiene más de un único fichero. No es posible pegar');
Exit;
end;
Buffer[0] := #0;
DragQueryFile( Hand, 0, buffer, sizeof(buffer)) ;
File_Name := buffer;
end;
finally
Clipboard.close;
end;

f := TFileStream.Create(File_Name, fmOpenRead);
Jpg := TJpegImage.Create;
Bitmap := TBitmap.Create;

// Check if Jpg File
try
Jpg.LoadFromStream(f);
ImageAux.Picture.Assign(Jpg);
Jpg_Bmp := 'JPG';
except
f.seek(0,soFromBeginning);
Jpg_Bmp := '';
end;

if Jpg_Bmp = '' then begin
try
Bitmap.LoadFromStream(f);
Jpg.Assign(Bitmap);
ImageAux.Picture.Assign(Jpg);
Jpg_Bmp := 'BMP';
except
Jpg_Bmp := '';
end;
end;

Jpg.Free;
Bitmap.Free;
f.Free;

if Jpg_Bmp = '' then begin
ImageAux.Free;
MessageError('Fichero seleccionado no contiene ninguna Imagen del Tipo JPEG o BMP');
Exit;
end;

end
else if Clipboard.HasFormat(CF_BITMAP) then
ImageAux.Picture.Assign(Clipboard)
else begin
ImageAux.Free;
MessageError('El Portapapeles no contiene ninguna Imagen del Tipo JPEG o BMP');
Exit;
end;

Jpg := TJpegImage.Create;
try
Jpg.Assign(ImageAux.Picture.Graphic);
except
ImageAux.Free;
MessageError('El Portapapeles no contiene ninguna Imagen del Tipo JPEG o BMP');
Jpg.Free;
Exit;
end;
Jpg.Free;

Image1.Picture.Assign(ImageAux.Picture);


Hago uso de ImageAux (de tipo TImage) para comprobar previamente la validez del contenido del portapapeles.

He hecho pruebas con varios programas (Adobe Acrobat, Word, Excel, ...) y la mayoría de ellos permiten que ImageAux.Picture.Assign(Clipboard) funcione, que se asigne una especie de 'Imagen' del contenido del portapapeles a un TImage.

Pero realmente no se trata en sí mismo, de un JPG o BMP, y es por ello que en operaciones posteriores daría error.

Quiero indicar que MessageError es una rutina propia, que muestra el error en pantalla. Y los diferentes 'Exit' los he dejado también tal cual ya que lo mostrado es parte de una rutina más amplia.

En el uses de la unit, aparte de otros, debereis incluid ClipBrd y JPEG.

Saludos y espero a alquien le pueda servir ;) ;)

martinartaza
20-10-2010, 15:09:55
Hola Gluglu, ya se que el hilo es viejo, mas de 6 años, lo que pasa que donde estoy trabajando estamos con delphi 6 y se necesita guardar imagen y pasarla a la base de datos y también lo había pensado como vos, que desde el navegador o desde el explorador de windows se pueda copiar, lo único que se agrega de complejidad es que necesito saber el tamaño del archivo seleccionado.

O sea que si se elije un archivo de más de 3 MB no deje hacer la operación o si la imagen que se copio en el portapapeles es mayor a 3 mb tampoco.

Bueno eso necesito, espero que leas el post y si tiene la respuesta la compartes como hiciste con el código anterior, mientras tanto voy a buscar como solucionar eso y también lo posteare.