[C#] Crop Image [RESOLU]

Bonjour à tous,

J’ai fait une petite appli en C# dont le but est de découper une grande image en petites images, par exemple une image qui fait 1000x1000px elle se découpe en 10 images qui font chacunes 100x100.

Sympa, mais Photoshop le fait très bien çà me direz-vous. Bah oui sur les images de petites tailles. Moi je veux découper des grosses images (10 000px, 240Mo env.) et Photoshop ne supporte pas. Et le problème, puisqu’il y a problème, c’est que la petite appli que j’ai faite ne fonctionne pas non plus :P. je l’ai testée avec un fichier de 60Mo, découpé par dalle de 400px, çà marche nickel, ensuite je l’ai testée avec un le fameux fichier de 10 000px et de 240Mo et la paf, une erreur.

Donc je ne sais pas trop comment faire si ce n’est user des ‘stream’ (hein joe :P) Mais seulement voilà je ne suis pas hyper calé là dessus et je ne vois pas trop comment m’y prendre concrètement.

Je vous donne la méthode qui permet de cropper :

[code]  private void cropImage(Image img, String savePath, int largeurD, int hauteurD)
 {    
 string path = savePath;
 int largeurImage = img.Width;
 int hauteurImage = img.Height;

 int largeurDalle = largeurD; // largeur de la petite image finale
 int hauteurDalle = hauteurD;  // hauteur de la petite image finale

 Bitmap bmpImage = new Bitmap(img);

 
 int countHauteur = 0;

&nbsp;for (int i=0; i<hauteurImage; i+=hauteurDalle)
&nbsp;{

   int countLargeur = 0;

   for (int j=0; j<largeurImage;  j+=largeurDalle)
   {
   
   Rectangle recCrop = new Rectangle(countLargeur, countHauteur, largeurDalle, 400);
   Bitmap bmpCrop = new Bitmap (largeurDalle, hauteurDalle, bmpImage.PixelFormat);
   Graphics gphCrop = Graphics.FromImage(bmpCrop);
   Rectangle recDest = new Rectangle(0, 0, largeurDalle, hauteurDalle);
   gphCrop.DrawImage(bmpImage, recDest, recCrop.X, recCrop.Y, recCrop.Width, recCrop.Height, GraphicsUnit.Pixel);

   bmpCrop.Dispose();
   gphCrop.Dispose();
 
   bmpCrop.Save(path+countHauteur.ToString()+"_" + countLargeur.ToString() + “.png”,ImageFormat.Png);

   countLargeur += largeurDalle;    
 
   }
   countHauteur += hauteurDalle;
 }
 bmpImage.Dispose();
 
 }[/code]

Merci de votre aide !

C’est un bitmap ? Si oui, pourquoi ne pas travailler directement sur les données brutes du fichier ?

Si c’est bien un bitmap, les pixels sont codés chacuns sur 3 octets (pour couleurs 24bits) ou un octet (256 couleurs, la palete est dans l’en tête), de gauche a droite et DE BAS EN HAUT.

Les spécifs doivent êtres quelques part dans la MSDN.

Deja une image 1000x1000 si tu la decoupe en 100x100 tu en auras pas 10 mais 100 :stuck_out_tongue:

Ensuite

[code]bmpCrop.Dispose();
gphCrop.Dispose();

bmpCrop.Save(path+countHauteur.ToString()+"_" + countLargeur.ToString() + ".png",ImageFormat.Png);[/code]

Tu sauves une images apres l’avoir disposé, c’est MAL.
Et tu fais tes Dispose dans le mauvais ordre.

Donc a la limite

[code] gphCrop.Dispose();

bmpCrop.Save(path+countHauteur.ToString()+"_" + countLargeur.ToString() + ".png",ImageFormat.Png);
bmpCrop.Dispose();[/code]

Ca me parait mieux. Le truc c’est d’utiliser using() {…} pour ca, ou try {…} finally {machin.Dispose();} de toute facon. C’est plus propre et ca t’evite ce genre de problemes.

Maintenant c’est quoi ton erreur exactement? Out of memory? Tu arrives a charger ta grosse image dans un Bitmap sans faire de manip dessus?

Ha ouai et enfin, pourquoi copier tes parametres dans des variables locales? Ca sert a rien. Et tes creations de rectangles, elles sont pas forcement necessaires. Mais bon c’est pas ca qui va faire planter ton code.

Bonjour,

déjà merci pour vos pistes.

Voici l’erreur.

et ici le contenu du message d’erreur Erreur en entier.

et tant qu’on y est, voici le code.

TZIM : ouai, c’est que du Bitmap. Mais tu veux dire que j’ouvre une partie de l’image source, je découpe, je ferme la partie de l’image, j’ouvre la partie suivante etc tout çà pour mieux faire passer la pillule ?

Nan tu tapes directement dans les octets du bitmap. Tu ouvres le fichier (et tu le mets pas entièrement en mémoire sinon tu vas avoir la meme erreur) tu déplace ton pointeur de fichier au bon endroit, tu copies les octets qui te faut, et tu bazarde dans un nouveau fichier.

Méthode très résumée (en fait faut choper les entêtes et les retravailler pour les faire colelr a ton nouveau bout de bitmap).

Ha putain mais je sais exactement ce qui tue ton programme c’est que tu clone l’image geante en memoire. Si une fois ca passe, deux fois il meurt le truc. Clair.

Tu prend en parametre une Image img et trois ligne apres tu fais Bitmap originalBmp = new Bitmap(img). Ca tue tout ca, c’est mal. Deja comme j’ai dit je comprend pas pourquoi tu duplique tes params dans des variables locales mais la, en plus tu double ton utilisation memoire comme tu peux voir dans la stack trace:

System.Drawing.Bitmap.ctor(Image original) <-- il cree une nouvelle image.

Donc je suis sur que ce que tu passe en entree de ta fonction c’est deja un Bitmap. Donc tu le caste en tant que Bitmap et tu le dispose pas a la fin de ta fonction. Je vois pas du tout l’interet du dupliquer ton image passee en parametre dans une autre image vu que tu fais que lire depuis l’image geante.

Si tu as reussit a rentrer dans ta fonction cropImage, tu es bon, tu peux faire ton decoupage, tu as pas besoin de lire l’image a partir du stream petit bout par petit bout ou quoi que ce soit de ce genre.

Il n’y a aucun intérêt en effet, c’est tout simplement parce que je suis une tanche, c’est tout !!! Bon en tout cas, j’essaie !!! et je vous tiens au courant

Merci à tous


C’était effectivement çà, çà fonctionne nickel :stuck_out_tongue:


Par contre, si je veux optimiser mon PNG, là faut que j’y aille octet par octet je suppose ?

J’avais lu un article sur la MSDN pour optimiser un gif une fois. Si quelqu’un a des billes là dessus je suis preneur.