PDA

Ver la Versión Completa : Validar Imagen


MaMu
22-05-2007, 06:16:42
Yo estoy haciendo un programa que muestra archivos de imagenes JPG y BMP en un TImage, pero como puedo hacer para validarlos, puesto a que yo, por ejemplo, puedo renombrar un archivo.txt a un archivo.jpg/archivo.bmp y me genera error al intentar cargalo, esto lo hago a modo de "error de lectura" como para poder contemplar esto. Existe alguna forma, es decir, hay algun encabezado o dato que pueda verificar que si existe en el archivo JPG o BMP, me lo valide y sino que lo descarte?

Saludos y gracias

BuenaOnda
22-05-2007, 06:52:20
Para validar que un archivo exista puedes utilizar la funcion FileExists, pero si tu pregunta es que valide que el archivo de imagen no este dañado, no se si podrá, tendrías que crear un captura de errores TRY / EXCEPT, esa es la forma que utilizo, espero que te sirva.:D

MaMu
22-05-2007, 09:19:44
Para validar que un archivo exista puedes utilizar la funcion FileExists, pero si tu pregunta es que valide que el archivo de imagen no este dañado, no se si podrá, tendrías que crear un captura de errores TRY / EXCEPT, esa es la forma que utilizo, espero que te sirva.:D

En realidad es ver si el archivo esta dañado.
Podrias ponerme un ejemplo de como usar TRY / EXCEPT para capturar cuando esta dañado?

A ver, yo lo entiendo asi, es correcto?


...
try
Image1.LoadFromFile('c:\imagen.jpg');
except
showmessage('Archivo Dañado');
Image1.LoadFromFile('c:\mi_imagen_para_el_error.jpg');
end;
...


Saludos y Gracias

Neftali [Germán.Estévez]
22-05-2007, 09:21:41
Podrías probar a mostrarlo en un TImage (puede estar oculto si no te interesa que se vea) a ver si genera algun error, posiblemente un EInvalidGraphic.

MaMu
22-05-2007, 09:31:34
Podrías probar a mostrarlo en un TImage (puede estar oculto si no te interesa que se vea) a ver si genera algun error, posiblemente un EInvalidGraphic.

Mmm, y como sería eso? Mi forma esta mal? Lo que quiero hacer es que si el archivo de imagen no es reconocido, me ponga la imagen de error.

MaMu
22-05-2007, 10:09:38
Esto es lo que hice, segun entiendo yo, pero no me captura le excepcion.
Tengo añadida JPEG en el uses.


...
try
Image1.Picture.LoadFromFile('c:\imagen.jpg');
except
on EInvalidGraphic do
begin
Image1.Picture.Graphic := nil;
DeleteFile('c:\imagen.jpg');
end;
end;
...

Neftali [Germán.Estévez]
22-05-2007, 10:09:41
... y como sería eso? Mi forma esta mal?

Más o menos me refería a eso.
No vi tu respuesta.
Yo intentaría capturar el tipo concreto del error; Algo así:

try
Image1.Picture.Bitmap.LoadFromFile('C:\Temp\Readme.bmp');
except
on E:EInvalidGraphic do begin
MessageDlg('Archivo Dañado o no es un tipo de imagen reconocido.', mtError, [mbOK], 0);
Image1.Picture.Bitmap.LoadFromFile('c:\mi_imagen_para_el_error.jpg');
end;
on E:EFOpenError do begin
MessageDlg('El archivo de imagen no existe.', mtError, [mbOK], 0);
end
else begin
MessageDlg('Error desconocido', mtError, [mbOK], 0);
end;
end;

MaMu
22-05-2007, 10:51:19
No importa como intente la captura de la excepcion, siempre me sale:

'JPEG error #42'

saltando todo el codigo de tratamiento.

Why?!?!

Neftali [Germán.Estévez]
22-05-2007, 12:51:52
No importa como intente la captura de la excepcion, siempre me sale:'JPEG error #42'

Pues yo he hecho la prueba renombrando un TXT a BMP e intentando cargarlo y me sale bien...
:confused: :confused: :confused:

Neftali [Germán.Estévez]
22-05-2007, 12:55:47
Pues he probado con un Readme.txt renombreado a Readme.bmp y readme.jpg y este código y me lo captura perfectamente.


procedure TForm1.Button1Click(Sender: TObject);
begin


try
Image1.Picture.LoadFromFile('C:\Temp\Readme.jpg');
except
on E:EInvalidGraphic do begin
MessageDlg('Archivo Dañado o no es un tipo de imagen reconocido.', mtError, [mbOK], 0);
Image1.Picture.LoadFromFile('c:\mi_imagen_para_el_error.jpg');
end;
on E:EFOpenError do begin
MessageDlg('El archivo de imagen no existe.', mtError, [mbOK], 0);
end
else begin
MessageDlg('Error desconocido', mtError, [mbOK], 0);
end;
end;
end;


Desactiva que salten las excepciones en diseño (Stop on Delphi exceptions) en el IDE.

MaMu
22-05-2007, 14:22:15
Hice todo, desactive eso del IDE, lo que yo hago es lo siguiente:



for z:=0 to Lista.Count-1 do
begin
CopiarArchivo(lista.Strings[z],dirtmp+'\'+ExtractFileName(lista.Strings[z]));
try
Image5.Picture.LoadFromFile(lista.Strings[z]);
except
on EInvalidGraphic do
begin
DeleteFile(dirtmp+'\'+ExtractFileName(lista.Strings[z]));
end;
on EFOpenError do
begin
DeleteFile(dirtmp+'\'+ExtractFileName(lista.Strings[z]));
end;
on EOutOfResources do
begin
DeleteFile(dirtmp+'\'+ExtractFileName(lista.Strings[z]));
end;
on E: EOSError do
begin
DeleteFile(dirtmp+'\'+ExtractFileName(lista.Strings[z]));
end;
on EReadError do
begin
DeleteFile(dirtmp+'\'+ExtractFileName(lista.Strings[z]));
end;
else begin
DeleteFile(dirtmp+'\'+ExtractFileName(lista.Strings[z]));
end;
end;


Pero no me borra el archivo que esta mal, me lo deja. Porque?

seoane
22-05-2007, 14:51:52
Interesante código manu, pero como no te andes con cuidado puedes quedarte sin fotos :D En concreto, los errores EOutOfResources y EOSError pueden producirse aunque el archivo sea valido, solo hace falta que pilles al windows en un "mal momento".

Por otro lado, comprueba que:

dirtmp+'\'+ExtractFileName(lista.Strings[z])

es verdaderamente la ruta del archivo.

Neftali [Germán.Estévez]
22-05-2007, 15:05:13
Pero no me borra el archivo que esta mal, me lo deja. Porque?

¿Lo has ejecutado paso a paso? ¿Exactamente por dónde está pasando?
Estaría bien que comprobaras antes de borrar si el archivo existe...

Wellnic
22-05-2007, 21:55:47
Para saber desde el principio si un fichero es una imagen (tenga la extensión que tenga) lo mejor es abrirlo en modo binario y comprobar si tiene determinada característica propia de ese archivo. Por ejemplo, los jpg siempre tienen la cadena JFIF en la 7ª posición:


procedure TForm1.Button1Click(Sender: TObject);
var fc: File;
tf: String;

begin
tf:= StringOfChar(#32, 4);//hace sitio para almacenar 4 caracteres
AssignFile(fc, 'C:\Imagen.jpg');
FileMode:= fmOpenRead; // abrir como solo lectura... por si acaso
Reset(fc, 1);
Seek(fc, 6); //situar el puntero en la 7ª posición
BlockRead(fc, tf[1], 4); //lee esos 4 bytes en la variable tf
CloseFile(fc);
If tf='JFIF' Then ShowMessage('Es una imagen JPG');
end;

Cada formato de imagen tiene sus características, que se pueden averiguar con cualquier editor hexadecimal.

seoane
22-05-2007, 22:03:24
Para saber desde el principio si un fichero es una imagen (tenga la extensión que tenga) lo mejor es abrirlo en modo binario y comprobar si tiene determinada característica propia de ese archivo. Por ejemplo, los jpg siempre tienen la cadena JFIF en la 7ª posición:

:confused: ¿Y si el archivo esta corrupto? ¿Le falta un trozo?, etc ... Si el propio método Loadfromfile no avisa por medio de excepciones de todos estos errores, para que vamos a complicarnos.