Naja, ich würde sagen, um ein Bild - welcher Art auch immer - in nur ZWEI Farben zu wandeln (und dithern), wandelt man es erstmal in Graustufen, bzw geht über die "Graustufen-Stufe".
Normalerweise rechnet man die einzelnen Phasen Rot/Grün/Blau zusammen, und zwar
ROT*3+Grün*5+Blau*1
(wobei 3, 5 und 1 nicht die korrekten Werte sind, die sind noch etwas anders)
Das ist so, weil die Farbphasen ja eine unterschiedliche Helligkeit haben.
Dann erhält man in dem Fall ein Ergebnis, das man durch 9 teilen muß.
Die richtigen Werte sind:
Rot: 0,299
Grün: 0,587
Blau 0,114
Und die ergeben zusammen 1.
ABER das wäre natürlich Overkill, da beispielsweise alles *299, *587 und *114 und dann /1000 zu rechnen.
Besser wäre es meiner Meinung nach, 3 Tabellen zu erstellen, die für
ROT 256 Werte enthalten von 0* 0,299 bis 255*0,299 (76)
GRÜN 256 Werte enthalten von 0* 0,587 bis 255*0,587 (150)
BLAU 256 Werte enthalten von 0*0,144 bis 255*0,144 (29)
oder NOCH besser, die Ergebnisse als WORDS zu machen, in 256er schritten.
Dann kann man indiziert auf die Tabellen zugreifen, erhält 3 Words, die man addiert und erhält dann im HIGHbyte davon einen Wert 0-255, der dem Grauwert entspricht.
OK, soweit, so gut.
Dann erstellt man NOCH eine Tabelle, die Dithers enthält.
BEISPIEL: Man erstellt 256 Blocks aus 16x16 Bits, d.h. man braucht 32 Byte pro "Block". Diese Blocks füllt man dann mit Pixeln, aber nicht von oben nach unten, sondern nach dem "regulären Raster" Prinzip:
Ich schreib jetzt mal als Hex rein, wie die Pixel in der Reihenfolge reinmüssen:
Code: Alles auswählen
00 C0 30 F0 0C CC 3C FC 03 C3 33 F3 0F CF 3F FF
80 40 B0 70 8C 4C BC 7C 83 43 B3 73 8F 4F BF 7F
20 E0 10 D0 2C EC 1C DC 23 E3 13 D3 2F EF 1F DF
A0 60 90 50 AC 6C 9C 5C A3 63 93 53 AF 6F 9F 5F
08 C8 38 F8 04 C4 34 F4 0B CB 3B FB 07 C7 37 F7
88 48 B8 78 84 44 B4 74 8B 4B BB 7B 87 47 B7 77
28 E8 18 D8 24 E4 14 D4 2B EB 1B DB 27 E7 17 D7
A8 68 98 58 A4 64 94 54 AB 6B 9B 5B A7 67 97 57
02 C2 32 F2 0E CE 3E FE 01 C1 31 F1 0D CD 3D FD
82 42 B2 72 8E 4E BE 7E 81 41 B1 71 8D 4D BD 7D
22 E2 12 D2 2E EE 1E DE 21 E1 11 D1 2D ED 1D DD
A2 62 92 52 AE 6E 9E 5E A1 61 91 51 AD 6D 9D 5D
0A CA 3A FA 06 C6 36 F6 09 C9 39 F9 05 C5 35 F5
8A 4A BA 7A 86 46 B6 76 89 49 B9 79 85 45 B5 75
2A EA 1A DA 26 E6 16 D6 29 E9 19 D9 25 E5 15 D5
AA 6A 9A 5A A6 66 96 56 A9 69 99 59 A5 65 95 55
Wenn Du willst, gebe ich da mal so Dithermasken für ASM aus, habe das schon hier generiert.
Das besteht aus 256*16 Words.
Das Ganze funktioniert nun so, daß man bei jedem Pixel folgendes tut:
Man nimmt die unteren 4 Bit der Zeilennummer als Y und die unteren 4 Bit der Spaltennummer.als X. Dann nimmt man die Grau-Helligkeit des Pixels (0 bis 255), nennen wir sie A.
Und aus (A+Y)*2 holt man ein Word und checkt das X-te Bit (indem man z.B. einfach Wert ROR (X+1) macht und Carry testet oder Wert ROR X und dann TEST WERT,1.
Jedenfalls erhält man damit, ob Farbe 0 oder 1 gesetzt werden muß, wobei 0 = schwarz , 1= weiß.
(also das Bit 0 des Wertes ist nach ROR Wert,X halt die Farbe).
Wer aufgepaßt hat, bemerkt, daß es eigentlich 257 Werte sein müßten, denn wenn man ein 16x16 Bitl Feld nacheinander mit Bits füllt, gibt es ja einen Null-Zustand (ohne Bits) und dann eben die 256 Zustände für jedes Bit, das dazukommt.
Ich persönlich würde das einfach ausgleichen, indem ich eine der Matrizen weglasse und dafür die "ganz leer" (0) und "ganz voll" (255) Matrix mit komplett mit Nullbits (für 0) und Einsbits (für 255) füllt.
Oder man macht die Tabellen für die Graustufen so, daß es 257 Grau-Werte gibt- Aber dann ist das alles nicht mehr so schön 8bit/16bit-basiert.
Ich sage mal so: Da man das Bild natürlich spalten-/zeilenweise durcharbeitet, braucht man natürlich nicht umständlich immer die Zeile oder Spalte "herausfinden", weil die sich ja normal erhöhen...
Das heißt: Für jede Stelle des Bildes wird entschieden, welcher Pixel da "angemessen" ist - das ist natürlich nur für das ganze Bild sinnvoll. Ein einzelner Bildpixel kann ja nur schwarz oder weiß sein und es hängt von der Graustufe UND seiner Position im Bild ab.
Man kann das ganze natürlich reduzieren, indem man keine 16x16- sondern eine 8x8-Pixel Matrix für das Dither benutzt.
Es gibt noch eine andere Möglichkeit - OHNE so feste Dither:
Man generiert genau solche Graustufen wie vorher. Und dann erzeugt man bei jedem Pixel einen Zufallswert zwischen 0 bis 255. Und wenn die Graustufe kleiner als der Zufallswert ist, macht man den Pixel schwarz, ansonsten weiß. Man kann sich auch eine kurze Tabelle solcher Zufallswerte machen und diese immer wiederholen lassen. (Dann braucht man sie nicht generieren.) Sie sollte nur nicht die gleiche Breite wie das Bild haben oder ein ganzzahliger Teiler dieser Breite sein, da man sonst ungewollte senkrechte Linien einbaut.
Ich könnte jetzt schon auf der Stelle ein kleines ASM-Programm schreiben, das genau das Obengesagte tut.
Ich hoffe, ich konnte mit diesen Anregungen etwas helfen.