web-dev-qa-db-fra.com

Une erreur générique s'est produite dans GDI + dans la méthode Bitmap.Save

Je travaille sur le téléchargement et la sauvegarde d'une copie miniature de cette image dans un dossier de miniatures.

J'utilise le lien suivant:

http://weblogs.asp.net/markmcdonnell/archive/2008/03/09/resize-image-before-uploading-to-server.aspx

mais 

newBMP.Save(directory + "tn_" + filename);   

est à l'origine de l'exception "Une erreur générique s'est produite dans GDI +."

J'ai essayé de donner la permission sur le dossier, j'ai aussi essayé d'utiliser un nouvel objet bmp séparé lors de la sauvegarde.

Modifier: 

    protected void ResizeAndSave(PropBannerImage objPropBannerImage)
    {
        // Create a bitmap of the content of the fileUpload control in memory
        Bitmap originalBMP = new Bitmap(fuImage.FileContent);

        // Calculate the new image dimensions
        int origWidth = originalBMP.Width;
        int origHeight = originalBMP.Height;
        int sngRatio = origWidth / origHeight;
        int thumbWidth = 100;
        int thumbHeight = thumbWidth / sngRatio;

        int bannerWidth = 100;
        int bannerHeight = bannerWidth / sngRatio;

        // Create a new bitmap which will hold the previous resized bitmap
        Bitmap thumbBMP = new Bitmap(originalBMP, thumbWidth, thumbHeight);
        Bitmap bannerBMP = new Bitmap(originalBMP, bannerWidth, bannerHeight);

        // Create a graphic based on the new bitmap
        Graphics oGraphics = Graphics.FromImage(thumbBMP);
        // Set the properties for the new graphic file
        oGraphics.SmoothingMode = SmoothingMode.AntiAlias; oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

        // Draw the new graphic based on the resized bitmap
        oGraphics.DrawImage(originalBMP, 0, 0, thumbWidth, thumbHeight);

        Bitmap newBitmap = new Bitmap(thumbBMP);
        thumbBMP.Dispose();
        thumbBMP = null;

        // Save the new graphic file to the server
        newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg);

        oGraphics = Graphics.FromImage(bannerBMP);
        // Set the properties for the new graphic file
        oGraphics.SmoothingMode = SmoothingMode.AntiAlias; oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

        // Draw the new graphic based on the resized bitmap
        oGraphics.DrawImage(originalBMP, 0, 0, bannerWidth, bannerHeight);
        // Save the new graphic file to the server
        bannerBMP.Save("~/image/" + objPropBannerImage.ImageId + ".jpg");


        // Once finished with the bitmap objects, we deallocate them.
        originalBMP.Dispose();

        bannerBMP.Dispose();
        oGraphics.Dispose();
    }
47
donstack

Lorsqu'un objet Bitmap ou un objet Image est construit à partir d'un fichier, le fichier reste verrouillé pendant la durée de vie de l'objet. Comme un Par conséquent, vous ne pouvez pas modifier une image et la sauvegarder dans le même fichier d'où il provient ... http://support.Microsoft.com/?id=814675

Une erreur générique s'est produite dans GDI +, Image JPEG dans MemoryStream

Image.Save (..) lève une exception GDI + car le flux de mémoire est fermé

http://alperguc.blogspot.in/2008/11/c-generic-erroroccocc-in-gdi.html

MODIFIER:
j'écris juste de mémoire ... 

enregistrer dans un flux de mémoire 'intermédiaire', cela devrait fonctionner

par exemple. essayez celui-ci - remplacez 

    Bitmap newBitmap = new Bitmap(thumbBMP);
    thumbBMP.Dispose();
    thumbBMP = null;
    newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg);

avec quelque chose comme: 

string outputFileName = "...";
using (MemoryStream memory = new MemoryStream())
{
    using (FileStream fs = new FileStream(outputFileName, FileMode.Create, FileAccess.ReadWrite))
    {
        thumbBMP.Save(memory, ImageFormat.Jpeg);
        byte[] bytes = memory.ToArray();
        fs.Write(bytes, 0, bytes.Length);
    }
}
78
NSGaga

Ce message d'erreur s'affiche également si le chemin que vous avez passé à Bitmap.Save() n'est pas valide (le dossier n'existe pas, etc.).

34
Reg Edit
    // Once finished with the bitmap objects, we deallocate them.
    originalBMP.Dispose();

    bannerBMP.Dispose();
    oGraphics.Dispose();

C’est un style de programmation que vous regretterez tôt ou tard. Plus vite, on frappe à la porte, vous en avez oublié un. Vous ne supprimez pas newBitmap. Ce qui garde un verrou sur le fichier jusqu'à ce que le garbage collector soit exécuté S'il ne s'exécute pas, la deuxième fois que vous essayez de sauvegarder dans le même fichier, vous obtiendrez le klaboom. Les exceptions GDI + sont trop misérables pour permettre un bon diagnostic. Au-delà des milliers de posts googlables qui mentionnent cette erreur.

Toujours favorise l'utilisation de l'instruction using. Qui n'oublie jamais de disposer d'un objet, même si le code lève une exception. 

using (var newBitmap = new Bitmap(thumbBMP)) {
    newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg);
}

Même s’il est très difficile de comprendre pourquoi vous créez même un nouveau bitmap, l’enregistrement de thumbBMP devrait déjà suffire. Anyhoo, donnez le même amour au reste de vos objets jetables.

9
Hans Passant

Vérifiez la permission de votre dossier où l’image est enregistrée Droit cCliquez sur le dossier puis allez:

Propriétés> Sécurité> Modifier> Ajouter - sélectionnez "Tout le monde" et cochez la case Autoriser le "Contrôle total".

6
Asad

Dans mon cas le fichier image bitmap existait déjà dans le lecteur système , mon application a donc renvoyé l'erreur "Une erreur générique s'est produite dans GDI +" .

  1. Vérifier que le dossier de destination existe
  2. Vérifiez qu'il n'y a pas déjà un fichier avec le même nom dans le dossier de destination
5
Palani Kumar

Je faisais face au même problème Une erreur générique s’est produite dans GDI + lors de la sauvegarde alors que je travaillais sur une application MVC, j’obtenais cette erreur parce que j’écrivais un chemin incorrect pour enregistrer une image, I chemin de sauvegarde corrigé et cela a fonctionné bien pour moi. 

img1.Save(Server.MapPath("/Upload/test.png", System.Drawing.Imaging.ImageFormat.Png);
3
Anjan Kant

Je l’ai obtenu avec FileStream, obtenez de l’aide auprès de ces utilisateurs.
http://alperguc.blogspot.in/2008/11/c-generic-error-occurring-in-gdi.htmlhttp://csharpdotnetfreak.blogspot.com/2010 /02/resize-image-upload-ms-sql-database.html

System.Drawing.Image imageToBeResized = System.Drawing.Image.FromStream(fuImage.PostedFile.InputStream);
        int imageHeight = imageToBeResized.Height;
        int imageWidth = imageToBeResized.Width;
        int maxHeight = 240;
        int maxWidth = 320;
        imageHeight = (imageHeight * maxWidth) / imageWidth;
        imageWidth = maxWidth;

        if (imageHeight > maxHeight)
        {
            imageWidth = (imageWidth * maxHeight) / imageHeight;
            imageHeight = maxHeight;
        }

        Bitmap bitmap = new Bitmap(imageToBeResized, imageWidth, imageHeight);
        System.IO.MemoryStream stream = new MemoryStream();
        bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
        stream.Position = 0;
        byte[] image = new byte[stream.Length + 1];
        stream.Read(image, 0, image.Length);
        System.IO.FileStream fs
= new System.IO.FileStream(Server.MapPath("~/image/a.jpg"), System.IO.FileMode.Create
, System.IO.FileAccess.ReadWrite);
            fs.Write(image, 0, image.Length);
1
donstack

Je vérifie/teste toujours ces:

  • Est-ce que le chemin d'accès + nom de fichier contient des caractères illégaux pour le système de fichiers donné?
  • Le fichier existe-t-il déjà? (Mal)
  • Le chemin existe-t-il déjà? (Bien)
  • Si le chemin est relatif: est-ce que je l'attends dans le bon répertoire parent (principalement bin/Debug ;-))?
  • Le chemin d'accès est-il accessible en écriture pour le programme et sous quel utilisateur est-il exécuté? (Les services peuvent être difficiles ici!)
  • Le chemin complet ne contient-il vraiment pas de caractères illégaux? (certains caractères unicode sont proches de l'invisible)

Je n'ai jamais eu de problème avec Bitmap.Save() en dehors de cette liste.

1

J'ai eu un problème différent avec la même exception.

En bref:

Assurez-vous que l'objet Bitmap's Stream n'est pas supprimé avant d'appeler .Save.

Histoire complète:

Il y avait une méthode qui renvoyait un objet Bitmap, construit à partir de MemoryStream de la manière suivante:

private Bitmap getImage(byte[] imageBinaryData){
    .
    .
    .
    Bitmap image;
    using (var stream = new MemoryStream(imageBinaryData))
    {
        image = new Bitmap(stream);
    }
    return image;
}

quelqu'un a ensuite utilisé l'image renvoyée pour l'enregistrer sous forme de fichier

image.Save(path);

Le problème était que le flux d'origine était déjà disposé lors de la tentative de sauvegarde de l'image en lançant l'exception GDI +.

Une solution à ce problème consistait à renvoyer la variable Bitmap sans supprimer le flux lui-même, mais à renvoyer l'objet Bitmap.

private Bitmap getImage(byte[] imageBinaryData){
   .
   .
   .
   Bitmap image;
   var stream = new MemoryStream(imageBinaryData))
   image = new Bitmap(stream);

   return image;
}

puis:

using (var image = getImage(binData))
{
   image.Save(path);
}
0
Yan

Créer le chemin du dossier image/pouce sur votre disque dur => Problème résolu!

0
Chưa biết

J'ai rencontré cette erreur en essayant de convertir des images Tiff en Jpeg. Pour moi, le problème tenait au fait que les dimensions du tiff étaient trop grandes. Quelque chose d’environ 62 000 pixels était acceptable, tout dépassant cette taille produisant l’erreur. 

0
RichTea88
    I used below logic while saving a .png format. This is to ensure the file is already existing or not.. if exist then saving it by adding 1 in the filename

Bitmap btImage = new Bitmap("D:\\Oldfoldername\\filename.png");
    string path="D:\\Newfoldername\\filename.png";
            int Count=0;
                if (System.IO.File.Exists(path))
                {
                    do
                    {
                        path = "D:\\Newfoldername\\filename"+"_"+ ++Count + ".png";                    
                    } while (System.IO.File.Exists(path));
                }

                btImage.Save(path, System.Drawing.Imaging.ImageFormat.Png);
0
Balaji Dinakaran

Pour moi, c'était un problème de permission. Quelqu'un a supprimé les autorisations d'écriture sur le dossier du compte d'utilisateur sous lequel l'application était en cours d'exécution.

0
Jenny O'Reilly

de msdn: public void Save (string filename); ce qui me surprend beaucoup car nous ne devons pas simplement indiquer le nom du fichier, nous devons également indiquer le nom du fichier, ainsi que le chemin d'accès: MyDirectory/MyImage.jpeg, ici MyImage.jpeg n'existe pas encore, mais notre fichier sera enregistré. avec ce nom.

Un autre point important ici est que si vous utilisez Save() dans une application Web, utilisez également Server.MapPath(), qui renvoie en gros le chemin physique du chemin virtuel transmis. Quelque chose comme: image.Save(Server.MapPath("~/images/im111.jpeg"));

0
Fakhar Ahmad Rasul

pour moi, c'était un problème de chemin lors de la sauvegarde de l'image.

int count = Directory.EnumerateFiles(System.Web.HttpContext.Current.Server.MapPath("~/images/savedimages"), "*").Count();

var img = Base64ToImage(imgRaw);

string path = "images/savedimages/upImages" + (count + 1) + ".png";

img.Save(Path.Combine(System.Web.HttpContext.Current.Server.MapPath(path)));

return path;

Alors je l'ai corrigé en ajoutant la barre oblique suivante

String path = "images/savedimages....

devrait être

String path = "/images/savedimages....

Espérons que cela aide quelqu'un coincé!

0
imBlue