Class Bitmap obscur [Résolu]

sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention - 22 avril 2005 à 03:12 - Dernière réponse : sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention
- 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
Afficher la suite 

Votre réponse

9 réponses

sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 22 avril 2005 à 12:04
+3
Utile
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>
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de sebmafate
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 22 avril 2005 à 10:25
0
Utile
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>
Commenter la réponse de sebmafate
sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention - 22 avril 2005 à 10:52
0
Utile
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.
Commenter la réponse de sebseb42
sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention - 22 avril 2005 à 11:07
0
Utile
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
Commenter la réponse de sebseb42
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 22 avril 2005 à 11:16
0
Utile
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>
Commenter la réponse de sebmafate
sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention - 22 avril 2005 à 11:48
0
Utile
je vais essayer, si elle marche je pourrais surement en utiliser un deriver, merci, je te tiens au courant
Commenter la réponse de sebseb42
sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention - 22 avril 2005 à 12:00
0
Utile
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...
Commenter la réponse de sebseb42
sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention - 22 avril 2005 à 12:16
0
Utile
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.
Commenter la réponse de sebseb42
sebseb42 495 Messages postés dimanche 6 juillet 2003Date d'inscription 9 novembre 2007 Dernière intervention - 22 avril 2005 à 12:20
0
Utile
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
Commenter la réponse de sebseb42

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.