Si un jpg invalide ne peut être chargé dans notre TImage, l'erreur sera traitée sans l'apparition de cette maudite fenêtre.
Le problème a été soulevé récemment par Gordo Cabron.
Si l'on veut charger une image au format jpg dans une TImage, il semblerait suffisant de protéger son code dans un bloc try...except...end.
Cela fonctionne dans le cas d'un fichier inexistant.
Mais en cas de fichier corrompu ou invalide, une fenêtre "Erreur JPEG #41" apparaît et empêche de traiter l'erreur de manière silencieuse ou autre...
Or, dans un programme de visualisation d'images auquel je travaille depuis un certain temps, je ne me rappelais pas avoir eu cette difficulté, ce qui m'a intrigué.
Après analyse, j'ai trouvé pourquoi :
dans mon code, je passe par un TBitmap, etc..., que j'assigne à un TJpegImage, avant affichage dans une TImage.
Du coup l'erreur se produit à un autre niveau, ce qui permet de la gérer sans l'apparition de cette fichue fenêtre, ce dont l'utilisateur de notre programme n'a que faire !
J'ai donc bossé un peu, et voici le résultat sous forme d'une fonction.
function LoadImageJpeg(FromFile: String; ToImage: TImage): Boolean;
Les arguments à passer sont : le chemin + nom du fichier jpg, le TImage où doit s'afficher l'image.
La valeur retournée est True si l'image est valide, False dans le cas contraire.
Je joins un exemple d'application de cette fonction dans le zip.
Et... petit clin d'oeil à Mauricio (va savoir pourquoi ?) ;)
ATTENTION : Mise à jour majeure, le code précédent était erronné !
Source / Exemple :
uses jpeg;
function LoadImageJpeg(FromFile: String; ToImage: TImage): Boolean;
var Bmp: TBitmap;
Jpg: TJpegImage;
begin
Result := True;
try
Bmp := TBitmap.Create;
Jpg := TJpegImage.Create;
try
Jpg.LoadFromFile(FromFile);
Bmp.Assign(Jpg);
ToImage.Picture.Assign(Bmp);
except
Result := False;
end;
finally
Jpg.Free;
Bmp.Free;
end;
end;
Conclusion :
Désolé pour les 9 ko de l'image dans le zip, mais j'ai pas eu le coeur de réduire davantage la qualité...
24 août 2006 à 22:25
function LoadImageJpeg(const FromFile: string; ToImage: TImage): Boolean;
var
Bmp: TBitmap;
Jpg: TJpegImage;
begin
Result := True;
Jpg := TJpegImage.Create;
try
try
Jpg.LoadFromFile(FromFile);
Bmp := TBitmap.Create;
try
Bmp.Assign(Jpg);
ToImage.Picture.Assign(Bmp);
finally
Bmp.Free;
end;
finally
Jpg.Free;
end;
except
Result := False;
end;
end;
On peut remarquer qu'en cas d'exception, je ne libère plus les ressources avant de les avoir créées, lol.
A plus...
24 août 2006 à 22:21
24 août 2006 à 22:19
Tu as l'intention d'éplucher tous mes vieux codes ? Moin il y a longtemps que je n'ose plus les regarder...
Pourtant, je l'aimais bien, celui-là.
Mais en le regardant mieux, je note que j'avais mal disposé les instructions à l'intérieur des blocs try ..except et try..finally.
Il apparaît également que ton astuce est plus efficace, car non seulement on économise du code, du temps et de la ressource, mais en plus on cerne précisément l'erreur déclenchée.
Voici quand même la correction de mon code (devenu inutile), en attendant la mise à jour.
Bon, Grandvizir n'avait pas tort, mais il a toujours eu le chic pour m'agacer...
24 août 2006 à 15:31
encore moi ... :-)
Voici un petit truc qui permet de caputer les exceptions JPEG #41, #52, #53 voir plus
je l'ai adapté à ton code et du coup on ne se sert plus de LoadImageJpeg
procedure TForm1.rgChoixClick(Sender: TObject);
var AnImage: String;
begin
case rgChoix.ItemIndex of
0: AnImage := 'Valid.jpg';
1: AnImage := 'NoImage.jpg';
2: AnImage := 'Invalid.jpg';
end;
AnImage := PathAppli + AnImage;
sbInfo.SimpleText := AnImage;
Try
Image1.Picture.LoadFromFile(AnImage);
// il suffit de faire un refresh avant ce qui permet la capture des exceptions en question
Image1.Refresh;
Except
ON E: Exception DO
begin
if cbMessage.Checked then
ShowMessage(E.Message); // la preuve ici ;-)
if cbClearImage.Checked then
Image1.Picture := nil;
End;
End;
end;
GrandVizir n'était pas loin il était sur la bonne piste.
Bien sur à tester en dehors de l'EDI
@+
Cirec
14 févr. 2005 à 15:11
try
Image.Picture.LoadFromFile(*.jpg);
except
on EInvalidGraphic do
DeleteFile(*.jpg);
end;
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.