2012-04-07 6 views
6

J'utilise cette ligne ci-dessous pour créer mon Bitmap:Obtenir le nom de fichier bitmap

Bitmap b = new Bitmap(@"C:\<file name>"); 

Après avoir modifier ce bitmap et je veux enregistrer comme en ligne ci-dessous:

b.Save(@"C:\\<other file name>") 

Ma question est - comment obtenir le bitmap de nom de fichier de la propriété.
En termes simples, j'ai besoin de sauvegarder l'image bitmap avec le nom avec lequel je l'ai initié.

Merci

+4

Vous n'obtenez aucune aide de Bitmap, il ne garde pas de trace d'un nom de fichier. Un bitmap ne doit pas non plus être créé à partir d'un fichier, il a plusieurs constructeurs. Vous aurez besoin de garder une trace de vous-même avec une variable de chaîne. –

+0

je comprends, merci! –

Répondre

5

Peut-être que vous pouvez faites ceci avec Metadata - mais je ne suis pas familier avec ce sujet donc je ne suis pas complètement sûr que c'est possible, et je ne sais pas comment le faire.
Ce que je faire suggère est de faire un type. Par exemple, vous pouvez créer une classe qui aura une propriété Bitmap(1) pour l'image, et une chaîne pour le chemin du fichier.

class LocalBitmap 
{ 
    public Bitmap Bitmap { get; set; } 
    public String Path { get; set; } 

    public LocalBitmap(String path) 
    { 
     Path = path; 
     Bitmap = new Bitmap(path); 
    } 
} 

et de l'utiliser comme ceci:

LocalBitmapimage = new LocalBitmap(@"C:\myImage.bmp"); 


(1) Pensez à utiliser la classe à la place Image. C'est la classe de base de Bitmap.Si vous n'êtes pas sûr de savoir lequel utiliser, demandez-vous si votre classe nécessite une image ou une image de ce format exact (c'est-à-dire, bitmap).

+0

Merci! C'est ce que je cherchais. –

5

Vous pouvez utiliser une variable:

var name = @"C:\<file name>"; 

puis:

using (Bitmap b = new Bitmap(name)) 
{ 
    ... 
    b.Save(name); 
} 

Notez également que j'ai enveloppé l'instance Bitmap dans une déclaration using afin de libérer non géré ressources qui lui sont associées dès que nous en avons fini avec elle. Vous devez toujours placer des objets IDisposable dans les instructions using.

+2

Le code affiché ne peut jamais fonctionner, il lève toujours une exception ExternalException. Le chargement d'un bitmap à partir d'un fichier verrouille le fichier, un verrou créé par la section de fichier mappé en mémoire que GDI + utilise pour mapper les données de pixels en mémoire. Le bitmap doit être disposé pour libérer le verrou. Beau problème de poulet et d'oeuf ici :) Utilisez le constructeur Bitmap (Image) pour créer la copie requise. –

0

Vous ne le faites pas. Simplement. Fondamentalement, le bitmap ne se souvient pas du fichier, c'est votre travail.

En gros, vous testez "Je reçois une image envoyée par UPS, après l'avoir déballée - quelques jours plus tard - comment puis-je trouver le numéro de livraison sur l'image?" - Tu ne le fais pas.

8

La réponse mise à jour va vous causer des ennuis. Le chargement d'un bitmap à partir d'un fichier verrouille le fichier. Vous ne pouvez pas le sauvegarder sans disposer d'abord le bitmap. Ce qui est un problème de poule et d'oeuf que vous ne pouvez pas résoudre sans cloner le bitmap. Ce qui est un peu délicat en soi, la méthode Bitmap.Clone() est une version optimisée qui utilise la même section de mémoire qui a mis le verrou sur le fichier en premier lieu. Donc, ne libère pas réellement le verrou.

Voici une petite classe qui prend soin de créer un clone profond et mémorise le chemin et le format du bitmap d'origine:

class EditableBitmap : IDisposable { 
     public EditableBitmap(string filepath) { 
      using (var bmp = new Bitmap(filepath)) { 
       this.bitmap = new Bitmap(bmp); 
       this.bitmap.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution); 
      } 
      this.path = System.IO.Path.GetFullPath(filepath); 
      this.format = bitmap.RawFormat; 
     } 

     public Bitmap Bitmap { get { return bitmap; } } 

     public void Save() { 
      bitmap.Save(path, format); 
      this.Dispose(); 
     } 

     public void Dispose() { 
      if (bitmap != null) { 
       bitmap.Dispose(); 
       bitmap = null; 
      } 
     } 
     private Bitmap bitmap; 
     private System.Drawing.Imaging.ImageFormat format; 
     private string path; 
    } 

Et l'utiliser comme ceci:

 using (var bmp = new EditableBitmap(@"c:\temp\test.png")) { 
      DoSomething(bmp.Bitmap); 
      bmp.Save(); 
     } 
+0

Pourquoi avez-vous besoin de stocker le ImageFormat? – gliderkite

+0

Parce que vous souhaitez normalement enregistrer le bitmap modifié avec le même format d'image. Ce n'est pas automatique lorsque vous utilisez Image.Save (chaîne), qui enregistre toujours au format PNG. –

0

Une autre façon de contourner le problème de verrouillage du fichier décrit par Hans est de freeze l'image.

public PhotoImageSource GetImage() 
{ 
    string filename = "c:\Images\myimage.png"; 
    var image = new BitmapImage(); 
    using (var stream = new FileStream(fileName, FileMode.Open)) 
    { 
     image.BeginInit(); 
     image.CacheOption = BitmapCacheOption.OnLoad; 
     image.StreamSource = stream; 
     image.EndInit(); 
    } 
    image.Freeze(); //prevent error "Must create DependencySource on same Thread as the DependencyObject" 
    return new PhotoImageSource(image, filename); 
} 

public class PhotoImageSource 
{ 
    public PhotoImageSource(ImageSource image, string filename) 
    { 
     Image = image; 
     Filename = filename; 
    } 
    public ImageSource Image { get; set; } 
    public string Filename { get; set; } 
} 
0

Un travail possible est autour d'utiliser la propriété Tag du Bitmap pour stocker le chemin sur la création ..

string pathToBitmap = @"C:\myImage.bmp"; 
Bitmap myBitmap = new Bitmap(pathToBitmap) { Tag = pathToBitmap }; 

..et puis récupérer le chemin plus tard ..

string pathFromBitmap = (string)myBitmap.Tag; 

.. assurez-vous de lancer le tag en tant que chaîne, et aussi de copier le tag à toutes les instances faites à partir du bitmap source.

Questions connexes