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

Signaler
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
-
Filipe35
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007
-
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 !

15 réponses

Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
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
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
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>
Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
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 ???
Messages postés
1039
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
24 avril 2013
2
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 ...
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007

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 !!
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007

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&#
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
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>
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007

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 !
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007

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&#
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
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>
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007

Merci ;)

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

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&#
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007

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&#
Messages postés
4200
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
2 janvier 2019
26
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%
Messages postés
496
Date d'inscription
vendredi 14 novembre 2003
Statut
Membre
Dernière intervention
23 octobre 2007

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&#