Ich verstehe Bitmap-Layout und Pixelformat Thema ziemlich gut, aber ein Problem beim Arbeiten mit png / jpeg Bilder durch NSImage
geladen - ich kann nicht herausfinden, ob das, was ich bekomme, ist das beabsichtigte Verhalten oder einen Fehler / p>
%Vor%
My kCGBitmapByteOrder32Host
ist Little Endian, was bedeutet, dass das Pixelformat in diesem Fall auch Little Endian - BGRA ist. Aber ... das PNG-Format ist Big Endian nach Spezifikation, und so sind die Bytes tatsächlich in den Daten angeordnet - entgegengesetzt von dem, was Bitmap-Informationen mir sagen.
Weiß jemand was los ist? Sicherlich weiß das System irgendwie, wie man damit umgeht, da PNGs korrekt angezeigt werden. Gibt es eine kugelsichere Möglichkeit, das Pixelformat von CGImage zu erkennen? Das vollständige Demo-Projekt ist unter GitHub verfügbar.
P. S. Ich kopiere rohe Pixeldaten über CFDataGetBytePtr
buffer in einen anderen Bibliothekspuffer, der dann verarbeitet und gespeichert wird. Um dies zu tun, muss ich das Pixelformat explizit angeben. Aktuelle Bilder, mit denen ich es zu tun habe (alle png / jpeg-Dateien, die ich überprüft habe), werden korrekt angezeigt, zum Beispiel:
Aber Bitmap-Informationen der gleichen Bilder geben mir falsche Endianness-Informationen, was dazu führt, dass die Bitmap als BGRA-Pixelformat statt als tatsächliches RGBA behandelt wird, wenn ich es verarbeite, sieht das Ergebnis so aus:
Das resultierende Bild zeigt den Farbwechsel zwischen roten und blauen Pixeln, wenn das RGBA-Pixelformat explizit angegeben wird, funktioniert alles perfekt, aber ich muss diese Erkennung automatisieren.
P. P. S. Dokumentation erwähnt kurz, dass CGColorSpace
eine weitere wichtige Variable ist, die das Pixelformat / die Byte-Reihenfolge definiert, aber ich habe keine Erwähnung gefunden, wie ich es dort rausholen kann.
Einige Jahre später und nachdem ich meine Ergebnisse in der Produktion getestet habe, kann ich sie mit gutem Vertrauen teilen, aber hoffe, dass jemand mit Theoriewissen die Dinge hier besser erklären kann? Gute Orte zum Auffrischen der Erinnerung:
Basierend darauf können Sie folgende Erweiterungen verwenden:
%Vor% Beachten Sie, dass Sie immer auf den Farbraum achten sollten - es wirkt sich direkt darauf aus, wie rohe Pixeldaten gespeichert werden. CGColorSpace(name: CGColorSpace.sRGB)
ist wahrscheinlich die sicherste - es speichert Farben im einfachen Format, zum Beispiel, wenn Sie mit rotem RGB umgehen, wird es genau so gespeichert (255, 0, 0), während der Gerätefarbraum Ihnen etwas wie (235 , 73, 53).
Um das in der Praxis zu sehen, fallen Sie oben und das Folgende in einen Spielplatz. Sie benötigen zwei ein Pixel große rote Bilder mit Alpha und ohne dies und das sollte funktionieren.
%Vor%Dies wird Folgendes ausgeben. Achten Sie darauf, wie sich das vom Bildschirm aufgenommene Bild von dem von der Festplatte geladenen Bild unterscheidet.
%Vor%
Könnten Sie NSBitmapFormat verwenden? ?
Ich habe eine Klasse geschrieben, um Farbschemata aus Bildern zu finden, und das habe ich benutzt, um das Bitmap-Format zu bestimmen. Hier ist ein Ausschnitt davon, wie ich es benutzt habe:
%Vor%Tags und Links bitmap swift core-graphics endianness