BMP -> JPG - Image jpeg toute verte [Résolu]

Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
- - Dernière réponse : Filipe35
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
- 16 mai 2006 à 14:26
Bonjour à tous,

je souhaiterais convertir des bmp en jpg
j'ai testé les 2 codes suivants

img := Timage.Create(self);
img.Picture.LoadFromFile(''bob.bmp);
img.Picture.SaveToFile(''bob.jpg);

et

nom := 'bob.bmp'; new := 'bob.jpg';
bmp := TBitmap.Create;
jpg := TJpegImage.Create;
// Le bitmap est lu
bmp.LoadFromFile(nom);
// La qualité choisie détermine le rendu de l'image et
// la taille prise sur le disque
jpg.CompressionQuality:=95;
// Image en couleur
jpg.GrayScale:=False;
// Copie du BMP dans le JPG
jpg.Assign(bmp);
// Et sauvegarde du JPG
jpg.SaveToFile(new);
Finally
jpg.Free;
bmp.Free;
End;

Le résultat de ces 2 codes est que l'image jpg est à forte dominante verte et inexploitable

avez vous une solution ?

Merci

Filipe

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le générateur de signatures !
Afficher la suite 

15 réponses

Meilleure réponse
Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
3
Merci
peut etre que ton image de depart est deja trop "verte" parce que j'ai teste chez moi ceci et tt est clair ! bizarre ...

sinon , ben non je n'ai pas d'autre soluce ...

desole

Ciao

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 221 internautes nous ont dit merci ce mois-ci

Commenter la réponse de Nicolas___
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
3
Merci
je me suis repencher sur le probleme.

et j'ai trouver que :

la signature d'un bitmap guildwars est de 38 octets ... contre 36 pour un bitmap normal.

donc decalage des couleurs.

voici deux fonctions qui te seront utile :

// recupere la taille d'un fichier
function SizeOfFile(filename : string) : int64;
var f : file of byte;
begin
result := 0;
try
AssignFile(f,FileName);
Reset(f);
result :=FileSize(f);
finally
closefile(f);
end;
end;

// transforme un bitmap GW en bitmap
function BMPGWtoBMP(filename : string) : string;
var x : integer;
s : int64;
fs,fd : file of byte;
c : byte;
n : string;
begin
// on recupere la taille du fichier

s := SizeOfFile(FileName);
// on crée le nom du fichier bmp temporaire

x := 0;
while fileexists('c:\bmpgw'+inttostr(x)+'.bmp') do inc(x);
n := 'c:\bmpgw'+inttostr(x)+'.bmp';

try
// on assigne et ouvre la source

AssignFile(fs,FileName);
reset(fs);
// on assigne et crée la source

AssignFile(fd,n);
rewrite(fd);

// la petite boucle lourdingue

for x := 1 to s do begin
// on lit le fichier

read(fs,c);
// on jump les deux octet genants

if (X <> 37) and (X <> 38) then write(fd,c);
end;
finally
// on ferme les fichiers

closefile(fs);
closefile(fd);
// on renvois le nom du fichier temporaire

result := n;
end;
end;

et dans la procedure d'ouverture du fichier :

procedure TForm1.Button1Click(Sender: TObject);
var tmp : string;
begin
if opendialog1.Execute then begin
if lowercase(extractfileext(opendialog1.FileName)) = '.bmp' then begin
{ ouverture du bitmap }
if GWCheckBox.Checked then begin
tmp := BMPGWtoBMP(opendialog1.FileName);
bmp.LoadFromFile(tmp);
else
bmp.LoadFromFile(opendialog1.filename);

{ parametres modifiable }
jpg.Grayscale := false;

jpg.CompressionQuality := 100; // [0..100]
jpg.Performance := jpBestQuality; // jpBestSpeed..jpBestQuality

jpg.ProgressiveEncoding := true;
jpg.Smoothing := false;
jpg.ProgressiveDisplay := true;

{ insertion du bitmap }
jpg.PixelFormat := jf8bit;
jpg.Compress; // appeler Compress a chaque modification de l'image
jpg.Assign(bmp); // assigne le bitmap
jpg.JPEGNeeded; // reinscrit les données jpeg

{ affichage }
image1.Picture.Bitmap.Width := jpg.Width;
image1.Picture.Bitmap.Height:= jpg.Height;
image1.Picture.Bitmap.Canvas.Draw(0,0,jpg);
end;
end;
end;

<hr size="2" width="100%">La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 221 internautes nous ont dit merci ce mois-ci

Commenter la réponse de f0xi
Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
0
Merci
salut
tu fais

var
JPG:TJPEGimage;
jpg:=Tjpegimage.Create;

jpg.Assign(image1.Picture.Bitmap); // image1.picture.bitmap peux etre remplacer par un bitmap
jpg.SaveToFile(NAME+'.jpg')

pour "faire" une bitmap

Var
bmp:Tbitmap

bmp:=TBitmap.create;
bmp.loadfromfile(blablabla.bmp);

jpg.Assign(bmp); //
jpg.SaveToFile(NAME+'.jpg')

Est ce clair ???
Commenter la réponse de Nicolas___
Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
0
Merci
procedure jpeg(image:string);
var
Jpg:tjpegimage;
bmp:TBitmap;
begin
bmp:=TBitmap.create;
jpg:=Tjpegimage.Create;


bmp.loadfromfile(image);


jpg.Assign(bmp);
jpg.SaveToFile('c:\'+Image+'.jpg')


end;

ps: n'oublie pas de mettre jpeg ds uses

apres tu peux jouer sur des parametyres genres

jpg.CompressionQuality
jpg.Grayscale
jpg.ProgressiveEncoding

etc ...
Commenter la réponse de Nicolas___
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Merci pour tes réponses, je les ai testéé toutes les deux mais j'obtiens toujours un jpg à dominante verte.

as tu une solution de secours ?

merci

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le générateur de sigantures !!
Commenter la réponse de Filipe35
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Mon image est un screenshot du jeu Guild Wars, elle est tout ce qu'il à de plus normale.

Si personnes n'a une solution, je devrais peut être prendre un compo spécifique, si vous en connaissez un bien je suis prenneur.

Merci

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le gén&#
Commenter la réponse de Filipe35
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
0
Merci
var
jpg : TJpegImage;
bmp : TBitmap;

procedure TForm1.FormCreate(Sender: TObject);
begin
jpg := jpeg.TJPEGImage.Create;
bmp := tbitmap.Create;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
jpg.Free;
bmp.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if opendialog1.Execute then begin
if lowercase(extractfileext(opendialog1.FileName)) = '.bmp' then begin
{ ouverture du bitmap }
bmp.LoadFromFile(opendialog1.FileName);

{ parametres modifiable }
jpg.Grayscale := false;

jpg.CompressionQuality := 100; // [0..100]
jpg.Performance := jpBestQuality; // jpBestSpeed..jpBestQuality

jpg.ProgressiveEncoding := true;
jpg.Smoothing := false;
jpg.ProgressiveDisplay := true;

{ insertion du bitmap }
jpg.PixelFormat := jf24bit;
jpg.Compress; // appeler Compress a chaque modification de l'image
jpg.Assign(bmp); // assigne le bitmap
jpg.JPEGNeeded; // reinscrit les données jpeg

{ affichage }
image1.Picture.Bitmap.Width := jpg.Width;
image1.Picture.Bitmap.Height:= jpg.Height;
image1.Picture.Bitmap.Canvas.Draw(0,0,jpg);
end;
end;
end;


procedure TForm1.Button3Click(Sender: TObject);
begin
if savedialog1.Execute then begin
jpg.Compress; // un dernier coups pour etre sur de l'avoir fait
jpg.SaveToFile(savedialog1.FileName);
end;
end;

<hr size="2" width="100%">La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
Commenter la réponse de f0xi
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Merci mais toujours le même problème malheureusement...

Penssez vous qu'utiliser un compo résoudra le problème ?

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le générateur ed signatures !
Commenter la réponse de Filipe35
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Sa marche nikel ! Merci beaucoup [auteurdetail.aspx?ID=360948 f0xi]

Dis moi comment as tu trouvé que les bmp guildwars étaient en 38 octects ? quelle différence (graphisque) par rapport à une 36 octets ?

Merci ;)

Filipe

PS: Grace à toi je vais pouvoir faire mon GW Screen Manager, je te mettrais dans les remerciements ;)

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le gén&#
Commenter la réponse de Filipe35
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
0
Merci
tout simplement en editant l'image a l'aide d'un editeur hexadecimal ...

<hr size="2" width="100%">La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
Commenter la réponse de f0xi
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Merci ;)

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le gén&#
Commenter la réponse de Filipe35
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Je viens de faire des test de performance, environ 15sec par image à 100% d'utilisation CPU :S
Aurais-tu une solution pour optimiser le code ?

Merci ;)

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le gén&#
Commenter la réponse de Filipe35
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Salut


J'ai le code suivant





s := SizeOfFile(FileName);



// on assigne et ouvre la source

AssignFile(fs,FileName);

reset(fs);

// on assigne et crée la source

AssignFile(fd,n);

rewrite(fd);



// A optimiser

for x := 1 to s do begin

// on lit le fichier

read(fs,c);

// on jump les deux octet genants

if (X <> 37) and (X <> 38) then write(fd,c);

end;

En remplacant la boucle par ces 2 boucles je gagne quelques ms



// la petite boucle lourdingue

for x := 1 to 36 do begin

read(fs,c);

write(fd,c);

end;



read(fs,c); // 37

read(fs,c); // 38



// la petite boucle lourdingue

for x := 39 to s do begin

// on lit le fichier

read(fs,c);

// On écrit

write(fd,c);

end;



Comment faire en sorte que cette suppression des bytes 37 et 38 soit plus rapide ?


Merci de tes réponses



Filipe

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le gén&#
Commenter la réponse de Filipe35
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
0
Merci
methode moins lourde ...

on appel le nom de l'image a convertir et on recupere le nom du fichier convertis...
on utilise les tfilestream pour aller plus vite et copier des bloc de donnée important (dans notre cas des fichiers de 2 a 3Mo)
en cas d'erreur (si le fichier n'existe pas) la fonction ne renvois rien.

function GW2BMP(const FileName : string) : string;
var Src,Dest : TFileStream;
begin
result := '';

if fileexists(FileName) then begin
result := ExtractFilePath(FileName)+'cnv_'+ExtractFileName(FileName);

Src := TFileStream.Create(FileName,fmOpenRead);
Dest := TFileStream.Create(result,fmCreate);

Dest.CopyFrom(Src,$36);
Src.Seek($38,soFromBeginning);
Dest.CopyFrom(Src,Src.Size-Src.Position);

Src.Free;
Dest.Free;
end;
end;

performances :

15ms pour 1 image et 1.600 sec pour convertir 25 images 1024x768
cpu load relevé 30%
Commenter la réponse de f0xi
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
0
Merci
Je vais tester ca le plus vite possible :P

Je ne connaissais pas vraiment cet avantage des streams et c'est l'occasion pour moi de m'y mettre ;)

Merci beaucoup f0xi pour tout le temps que tu as accordé à mon problème

++ et bonne continuation

Filipe

__________________________________________________
http://www.OgameTut.Free.Fr - Le site sur ogame de référence !
http://Signz.free.fr - Le gén&#
Commenter la réponse de Filipe35