Class Bitmap obscur

Résolu
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 - 22 avril 2005 à 03:12
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 - 22 avril 2005 à 12:20
Salut a tous, j'ai un truc plutot bizarre, je cherche a compresser des images a la voler sans passer par le disque-dur.

je fait ceci :

public Truc(Bitmap img) // ici je recoie une image de type BMP (qui fait 3.51 Mo)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
new_image = new Bitmap(ms); // ici mon image PNG fait 4 Mo :S
ms.Close();
}

alors j'ai tenter une autre approche pour tester un truc, et la je tombe sur un truc encore plus bizzar :

public Truc(Bitmap img) // toujours mon image de type BMP (3.51 Mo)
{
img.Save("c:\\test.tmp", System.Drawing.Imaging.ImageFormat.Png);
new_image = new Bitmap("c:\\test.tmp");
MemoryStream ms = new MemoryStream();
new_image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] buffer = ms.GetBuffer();
int len = buffer.Length; // ici len fait 4 Mo :S
}

pour le deuxieme bout de code, ce que j'aimerais qu'on m'explique c'est pourquoi dans ce cas precis mon fichier c:\test.tmp a bien ete compresser a 2,51Mo ?

Merci d'avance pour votre aide

9 réponses

sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 38
22 avril 2005 à 12:04
mouaip... mais moi je retourne un tableau de byte... pas le buffer...
enfin... en gros... ca change pas grand chose :(

Sébastien FERRAND

Blog :
http://blogs.developpeur.org/sebmafate</FO< body>
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 38
22 avril 2005 à 10:25
attention... il ne faut pas confondre espace disque et occupation mémoire.

Sur le disque ton image est compression, lorsque tu l'ouvres, il l'a décompresse en mémoire, ce qui explique ton 4Mo.

Sébastien FERRAND

Blog :
http://blogs.developpeur.org/sebmafate</FO< body>
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
22 avril 2005 à 10:52
Ouais je sais mais, le champs de bit est le meme pour toutes images de meme taille en pixels quelque soit la compression :) je me suis mal exprimer, desoler :)

En fait je tentais de mettre quelque chose en evidence, quelque chose que je n'ai pas montrer, autant pour moi :)

MemoryStream ms =
new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Close();

return (ms.GetBuffer());

Ceci, quand je fait img.Save enregistre dans un fichier et compresse, le fait d'utiliser un stream permet de pouvoir ensuite travailler avec un espace memoire et evite de passer inutilement par le disque dur. En theorie, le MemoryStream est censer substituer un fichier du disque dur, donc le MemoryStream devrait contenir un buffer similaire a celui qui se trouve sur le disque dur, c'est a dire un buffer ou la donnee d'image est compresser.

Au return, le ms.GetBuffer().Length est toujours de 4 Mo, et ceci n'est pas normal... du moins pas a ma connaissance.
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
22 avril 2005 à 11:07
en faisant ceci, ca fonctionne :

img.Save("c:\\temp.tmp", System.Drawing.Imaging.ImageFormat.Png);
StreamReader sr =
new StreamReader("c:\\temp.tmp");
BinaryReader br =
new BinaryReader(sr.BaseStream);

byte[] buffer = br.ReadBytes((
int)sr.BaseStream.Length);

Mais ce n'est pas ce que je veux, si quelqu'un a un moyen de faire ceci sans passer par le disque et tout en gardant un buffer compresser, je suis preneur

Merci d'avance
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 38
22 avril 2005 à 11:16
Moi je procède comme cela :

MemoryStream ms
=
new MemoryStream();

ImageCodecInfo PNGCodec =
null;

Encoder PNGEncoder =
null;

ImageCodecInfo[] icis = ImageCodecInfo
.GetImageEncoders();

foreach(ImageCodecInfo ici
in icis) {

if (ici
.FormatDescription

"PNG") {

PNGCodec = ici;

break;

}
}

if (PNGCodec

null)

return
null;

PNGEncoder =
new Encoder(PNGCodec
.Clsid);

EncoderParameters PNGParams =
new EncoderParameters();

PNGParams.Param
=
new EncoderParameter[] {
new EncoderParameter
PNGEncoder,
255)};

img.Save(ms, PNGCodec, PNGParams);

return ms
.ToArray();

Ce n'est pas forcément la meilleur méthode... mais bon

Sébastien FERRAND

Blog :
http://blogs.developpeur.org/sebmafate</FO< body>
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
22 avril 2005 à 11:48
je vais essayer, si elle marche je pourrais surement en utiliser un deriver, merci, je te tiens au courant
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
22 avril 2005 à 12:00
bon bah ta methode ne semble pas fonctionner non plus :S

MemoryStream ms =
new MemoryStream();
ImageCodecInfo PNGCodec =
null;
Encoder PNGEncoder =
null;
ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();

foreach(ImageCodecInfo ici
in icis)
{

if (ici.FormatDescription == "PNG")
{
PNGCodec = ici;

break;
}
}

if (PNGCodec ==
null)

return (
null);
PNGEncoder =
new Encoder(PNGCodec.Clsid);
EncoderParameters PNGParams =
new EncoderParameters();
PNGParams.Param =
new EncoderParameter[] {
new EncoderParameter(PNGEncoder, 255)};
img.Save(ms, PNGCodec, PNGParams);

return (ms.GetBuffer()); // 4Mo :S

J'ai l'impression que c'est le MemoryStream qui chie dans la colle...
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
22 avril 2005 à 12:16
Lol, bah en fait par une simple la plus banal qui soit, jeter presque dans le vide, j'ai decouvert ceci :

byte[] buffer1 = ms.ToArray(); // 2.4 Mo
byte[] buffer2 = ms.GetBuffer(); // 4 Mo

:S Bah en tout cas merci, de ce fait je peux reutiliser mon ancienne methode qui permet d'utiliser le codec PNG plus facilement :)

Je pense que GetBuffer renvoie le champs de bit non compressé, la donnée au format BMP et avec un codage des couleurs definit par PixelFormat.
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
22 avril 2005 à 12:20
arf, je dis de la merde, le MemoryStream n'as strictement aucune idee de comment est faite l'image :S je comprend pas comment ca se fait ni qu'elle est la reelle difference entre GetBuffer et ToArray puisque je pensais qu'il faisait tout les deux une espece de


return (_internal_buffer);


ou un truc dans le style, amais bon ca fonctionne... c'est etrange et j'aimerais quand meme bien savoir ce qui se passe, si quelqu'un connait ?


Merci
0