/// <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;
}
}