Fehler bei der Pixelreihenfolge beim Speichern und Laden von Gray16 mit WriteableBitmap

  • WPF

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Fehler bei der Pixelreihenfolge beim Speichern und Laden von Gray16 mit WriteableBitmap

    Die Fortsetzung von diesem Thread hier.
    Ich erzeuge ein rechteckiges 16-Bit-Testbild und speichere es mit diesem Code:

    C#-Quellcode

    1. WriteableBitmap bitmap = new WriteableBitmap(this.Header.Width, this.Header.Height, 96, 96, PixelFormats.Gray16, null);
    2. bitmap.WritePixels(new Int32Rect(0, 0, this.Header.Width, this.Header.Height), this.Data, this.Header.Width * 2, 0);
    3. PngBitmapEncoder encoder = new PngBitmapEncoder();
    4. encoder.Frames.Add(BitmapFrame.Create(bitmap));
    5. using (FileStream stream = File.Create(path))
    6. {
    7. encoder.Save(stream);
    8. }
    Geladen wird es mit diesem Code:

    C#-Quellcode

    1. BitmapDecoder decoder = null;
    2. try
    3. {
    4. decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
    5. BitmapFrame bmp = decoder.Frames[0];
    6. int stride = bmp.PixelWidth * 2;
    7. this.Data = new ushort[bmp.PixelWidth, bmp.PixelHeight];
    8. // diese 1-D-Array-Instanz muss erstellt werden,
    9. // sonst funktioniert CopyPixels nicht
    10. ushort[] array1D = new ushort[bmp.PixelWidth * bmp.PixelHeight];
    11. // Pixel aus dem stream auslesen
    12. bmp.CopyPixels(array1D, stride, 0);
    13. // Copy 1D zu 2D
    14. System.Buffer.BlockCopy(array1D, 0, this.Data, 0, bmp.PixelHeight * bmp.PixelWidth * 2);
    15. }
    16. catch
    17. {
    18. return false;
    19. }
    20. return true;
    Das Testbild sieht so aus:

    das gespeicherte Bild sieht so aus:

    Wenn dieses Bild wieder eingelesen wird, wird es richtig dargestellt.
    Am quadratischen Testbild habe ich festgestellt, dass Zeilen und Spalten getauscht abgespeichert werden.
    Nun habe ich mir eine Hin-Tausch- und eine Rück-Tausch-Routine gebaut, so dass die gespeicherten Bilder gut aussehen.
    Mit Rücktausch beim Einlesen werden auch fremde Bilder ordentlich behandelt.
    Kennt jemand diesen Effekt (ich nehme an, dass er auf Gray16-Bilder beschränkt ist) und weiß, wie man ihn "ordentlich" beheben kann?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Da hätte ich auch selbst drauf kommen können. ;(
    Ursache ist, dass in dem Programm das Pixel-Array 2-Dimensional angelegt wird, this.Data = new ushort[width, height].
    Nun läuft aber der 2. Index schneller als der 1., also liegen die Bilder spaltenweise im Speicher. Das muss beim Speichern und Lesen umsortiert werden und alles ist fein.
    Da das ein älteres Programm ist, wo sich schon mehrere Leute dran ausgetobt haben, habe ich nun die Hinten-Karte gezogen und muss den ganzen Sumpf trockenlegen.
    Und da da nix aber auch gar nix kommentiert ist, na gut...
    Jedenfalls erledigt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!