Feedback

C# - (WPF) Bilddateien einfach öffnen und speichern - in 2 Zeilen

Veröffentlicht von am 3/13/2014
(0 Bewertungen)
Zu meinem Geburtstag mal ein etwas längeres Snippet :)

Diese Klasse dient dem speichern bzw. öffnen von Bildern. Das ist alles nicht wirklich schwer, aber ist doch einige Codezeilen lang. Ich habe das alles nun mal zusammen gefasst und eine Hilfsklasse dafür erstellt. So verkürzt es sich nun bis auf minimal 2 Zeilen. Je nach Einstellung kann es aber mehr werden.

Beispielanwendung
Einlesen einer Datei vom Benutzer in ein Image-Control:
ImageFileHelper ifh = new ImageFileHelper();
image1.Source = new BitmapImage(ifh.Open());

Speichern des Bildes im Image-Control durch den Benutzer:
ImageFileHelper ifh = new ImageFileHelper();
ifh.Save(image1.Source as BitmapSource);//Die Konvertierung muss natürlich funktionieren


Benötigte Namespaces
System
System.Collections.Generic
System.IO
System.Text
System.Windows.Media.Imaging
Microsoft.Win32
System.Linq
/// <summary>
/// Stellt Methoden zum speichern und Öffnen von Bilddateien bereit.
/// </summary>
public sealed class ImageFileHelper
{
    /// <summary>
    /// Erstellt eine neue Instanz der <see cref="ImageFileHelper"/>-Klasse.
    /// </summary>
    public ImageFileHelper()
    {
        this.AllowedExtensions = new List<ImageFileExtensions>();
    }

    /// <summary>
    /// Ruft das Ausgangsverzeichnis der Datei-Dialoge ab oder legt dieses fest.
    /// </summary>
    public string InitialDirectory { get; set; }
    /// <summary>
    /// Ruft den Standardmäßigen Dateinamen ab oder legt diesen fest.
    /// </summary>
    public string InitialFileName { get; set; }
    /// <summary>
    /// Ruft die verfügbaren Dateierweiterungen ab oder legt diese fest.
    /// </summary>
    public List<ImageFileExtensions> AllowedExtensions { get; set; }
    /// <summary>
    /// Ruft Metainformationen über ein zu speicherndes Bild ab oder legt diese fest.
    /// </summary>
    public BitmapMetadata Metadata { get; set; }
    /// <summary>
    /// Ruft die Farbpalette über ein zu speicherndes Bild ab oder legt dieses fest.
    /// </summary>
    public BitmapPalette Palette { get; set; }
    /// <summary>
    /// Ruft das Vorschaubild einer zu speichernden Datei ab oder legt diese fest.
    /// </summary>
    public BitmapSource Thumbnail { get; set; }

    /// <summary>
    /// Zeigt dem Benutzer einen Öffnen-Dialog an und gibt den ausgewählten Dateinamen zurück.
    /// </summary>
    /// <returns>Der vom Benutzer ausgewählte Dateiname. Wenn der Benutzer den Vorgang abbricht, dann wird <c>null</c> zurück gegeben.</returns>
    public Uri Open()
    {
        return Open(GetOFD(false));
    }

    /// <summary>
    /// Zeigt dem Benutzer einen Öffnen-Dialog an und gibt die ausgewählten Dateinamen zurück.
    /// </summary>
    /// <returns>Die vom Benutzer ausgewählte Dateinamen. Wenn der Benutzer den Vorgang abbricht, dann wird <c>null</c> zurück gegeben.</returns>
    public IEnumerable<Uri> OpenMultiple()
    {
        return OpenMultiple(GetOFD(true));
    }

    /// <summary>
    /// Zeigt dem Benutzer einen Speichern-Dialog an und speichert das angegebene Bild an dem ausgewählten Ort.
    /// </summary>
    /// <param name="image">Das zu speichernde Bild.</param>
    /// <returns><c>true</c> wenn das Bild erfolgreich gespeichert wurde. Sollte der Benutzer den Vorgang abgebroch haben, dann wird <c>false</c> zurück gegeben.</returns>
    public bool Save(BitmapSource image)
    {
        return Save(image, GetSFD());
    }
    /// <summary>
    /// Zeigt dem Benutzer einen Speichern-Dialog an und gibt den ausgewählten Pfad zurück.
    /// </summary>
    /// <returns>Der vom Benutzer ausgewählte Pfad. Sollte der Benutzer den Vorgang abgebroch haben, dann wird <c>null</c> zurück gegeben.</returns>
    public string Save()
    {
        var sfd = GetSFD();
        if (sfd.ShowDialog() == true)
            return sfd.FileName;
        else
            return null;
    }

    /// <summary>
    /// Wird ausgelöst, wenn der Benutzer eine Qualitätsstufe für das zu speichernde Bild auswählen kann.
    /// </summary>
    public event EventHandler<QualitiyRequiredEventArgs> QualitiyRequired;

    Uri Open(OpenFileDialog ofd)
    {
        if (ofd.ShowDialog() == true)
        {
            return new Uri(ofd.FileName, UriKind.RelativeOrAbsolute);
        }
        else
            return null;
    }
    IEnumerable<Uri> OpenMultiple(OpenFileDialog ofd)
    {
        if (ofd.ShowDialog() == true)
        {
            foreach (var file in ofd.FileNames)
                yield return new Uri(ofd.FileName, UriKind.RelativeOrAbsolute);
        }
    }
    bool Save(BitmapSource image, SaveFileDialog sfd)
    {
        if (sfd.ShowDialog() == true)
        {
            var enc = GetEncoder(image, sfd);
            using (Stream sw = new FileStream(sfd.FileName, FileMode.Create))
            {
                enc.Save(sw);
            }
            return true;
        }
        return false;
    }

    private BitmapEncoder GetEncoder(BitmapSource image, SaveFileDialog sfd)
    {
        BitmapEncoder enc = null;
        switch (sfd.FileName.ToLower().Split('.').Last())
        {
            case "png":
                enc = new PngBitmapEncoder();
                break;
            case "jpg":
            case "jpeg":
                enc = new JpegBitmapEncoder()
                {
                    QualityLevel = GetQualitiy(ImageFileExtensions.JPG),

                };
                break;
            case "bmp":
            case "dif":
                enc = new BmpBitmapEncoder();
                break;
            case "tif":
            case "tiff":
                enc = new TiffBitmapEncoder();
                break;
            case "gif":
                enc = new GifBitmapEncoder();
                break;
            case "wmp":
                enc = new WmpBitmapEncoder()
                {
                    QualityLevel = GetQualitiy(ImageFileExtensions.WMP),
                };
                break;
            default:
                return null;
        }
        if (this.Thumbnail != null)
            enc.Thumbnail = this.Thumbnail;
        if (this.Palette != null)
            enc.Palette = this.Palette;
        if (this.Metadata != null)
            enc.Metadata = this.Metadata;
        enc.Frames.Add(BitmapFrame.Create(image));

        return enc;
    }

    private byte GetQualitiy(ImageFileExtensions imageType)
    {
        var evt = this.QualitiyRequired;
        if (evt != null)
        {
            QualitiyRequiredEventArgs e = null;
            switch (imageType)
            {
                case ImageFileExtensions.JPG:
                    e = new QualitiyRequiredEventArgs(1, 100, 94, imageType);
                    break;
                case ImageFileExtensions.WMP:
                    e = new QualitiyRequiredEventArgs(1, 255, 1, imageType);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            evt(this, e);
            return e.Quality;
        }
        return 94;
    }

    #region create FileDialog instances

    OpenFileDialog GetOFD(bool multiSelect)
    {
        return new OpenFileDialog()
        {
            Filter = GetFilter(this.AllowedExtensions),
            InitialDirectory = this.InitialDirectory,
            Multiselect = multiSelect,
            FileName = this.InitialFileName,
        };
    }
    SaveFileDialog GetSFD()
    {
        return new SaveFileDialog()
        {
            Filter = GetFilter(this.AllowedExtensions),
            InitialDirectory = this.InitialDirectory,
            FileName = this.InitialFileName,
        };
    }

    string GetFilter(List<ImageFileExtensions> allowedExtensions)
    {
        StringBuilder filterBuilder = new StringBuilder();
        if (allowedExtensions == null || allowedExtensions.Contains(ImageFileExtensions.PNG))
            AppendFilter(filterBuilder, ImageFileExtensions.PNG);
        if (allowedExtensions == null || allowedExtensions.Contains(ImageFileExtensions.JPG))
            AppendFilter(filterBuilder, ImageFileExtensions.JPG);
        if (allowedExtensions == null || allowedExtensions.Contains(ImageFileExtensions.BMP))
            AppendFilter(filterBuilder, ImageFileExtensions.BMP);
        if (allowedExtensions == null || allowedExtensions.Contains(ImageFileExtensions.TIFF))
            AppendFilter(filterBuilder, ImageFileExtensions.TIFF);
        if (allowedExtensions == null || allowedExtensions.Contains(ImageFileExtensions.GIF))
            AppendFilter(filterBuilder, ImageFileExtensions.GIF);
        if (allowedExtensions == null || allowedExtensions.Contains(ImageFileExtensions.All))
            AppendFilter(filterBuilder, ImageFileExtensions.All);
        return filterBuilder.ToString();
    }
    void AppendFilter(StringBuilder filterBuilder, ImageFileExtensions extension)
    {
        if (filterBuilder.Length != 0)
            filterBuilder.Append("|");

        switch (extension)
        {
            case ImageFileExtensions.PNG:
                filterBuilder.Append("Portable Network Graphic (*.PNG)|*.png");
                break;
            case ImageFileExtensions.JPG:
                filterBuilder.Append("JPEG (*.JPEG;*.JPG)|*.jpeg;*.jpg");
                break;
            case ImageFileExtensions.BMP:
                filterBuilder.Append("Bitmap (*.BMP)|*.bmp");
                break;
            case ImageFileExtensions.TIFF:
                filterBuilder.Append("TIFF (*.TIFF;*.TIF)|*.tiff;*.tif");
                break;
            case ImageFileExtensions.GIF:
                filterBuilder.Append("GIF (*.GIF)|*.gif");
                break;
            case ImageFileExtensions.WMP:
                filterBuilder.Append("Windows Media Photo (*.WMP)|*.wmp");
                break;
            case ImageFileExtensions.All:
                filterBuilder.Append("All Files|*.*");
                break;
        }
    }

    #endregion
}

/// <summary>
/// Repräsentiert die verfügbaren Dateierweiterungen.
/// </summary>
public enum ImageFileExtensions
{
    /// <summary>
    /// Das Bild kann im PNG-Format geöffnet und gespeichert werden.
    /// </summary>
    PNG,
    /// <summary>
    /// Das Bild kann im JPG-Format geöffnet und gespeichert werden.
    /// </summary>
    JPG,
    /// <summary>
    /// Das Bild kann im BMP-Format geöffnet und gespeichert werden.
    /// </summary>
    BMP,
    /// <summary>
    /// Das Bild kann im TIFF-Format geöffnet und gespeichert werden.
    /// </summary>
    TIFF,
    /// <summary>
    /// Das Bild kann im GIF-Format geöffnet und gespeichert werden.
    /// </summary>
    GIF,
    /// <summary>
    /// Das Bild kann im WMP-Format geöffnet und gespeichert werden.
    /// </summary>
    WMP,
    /// <summary>
    /// Das Bild kann iin einem beliebigen Format geöffnet und gespeichert werden. (Filter: Alle Dateien)
    /// </summary>
    All,
}

/// <summary>
/// Stellt Ereignisinformationen bereit um eine Anforderung einer Qualitätsangabe zu verarbeiten.
/// </summary>
public sealed class QualitiyRequiredEventArgs : EventArgs
{
    /// <summary>
    /// Ruft die Ausgewählte Qualität ab oder legt diese fest.
    /// </summary>
    public byte Quality { get; set; }
    /// <summary>
    /// Ruft den kleinst-möglichen Wert für <paramref name="Quality"/> ab.
    /// </summary>
    public byte Minimum { get; private set; }
    /// <summary>
    /// Ruft den größt-möglichen Wert für <paramref name="Quality"/> ab.
    /// </summary>
    public byte Maximum { get; private set; }
    /// <summary>
    /// Ruft das Format ab, in für das die Qualitätsangabe gelten soll.
    /// </summary>
    public ImageFileExtensions Type { get; set; }

    /// <summary>
    /// Erstellt eine neue Instanz der <see cref="QualitiyRequiredEventArgs"/>-Klasse.
    /// </summary>
    /// <param name="minimum">Das Minimum für <paramref name="quality"/>.</param>
    /// <param name="maximum">Das Maximum für <paramref name="quality"/>.</param>
    /// <param name="quality">Die Standardmäßig gesetzte Qualität.</param>
    /// <param name="type">Der Typ des zu speichernden Bildes.</param>
    public QualitiyRequiredEventArgs(byte minimum, byte maximum, byte quality, ImageFileExtensions type)
    {
        this.Minimum = minimum;
        this.Maximum = maximum;
        this.Quality = quality;
        this.Type = type;
    }
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!