24 Bit einer Palette anpassen

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

JPD

Betreff: 24 Bit einer Palette anpassen

BeitragMi, Jul 26, 2006 14:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

wie kann ich es schaffen, ein Bild mit 24 Bit einer Palette mit 256 Farben anzupassen. Die Palette hat das ACT-Format, ausgelesen wird das Ganze in 3 Feld mit R, G und B.

Mein Problem ist es nun, die Farben des 24-Bit-Bildes der Palette anzupassen. Wie geht sowas? Mit einer Farbe (Graustufen) würde ich das ganze noch verstehen, aber wie schauts mit 3 aus?

mfg JPD

Jan_

Ehemaliger Admin

BeitragMi, Jul 26, 2006 14:37
Antworten mit Zitat
Benutzer-Profile anzeigen
24bit = 16777216Fraben
8bit =256 Farben

--> wir können nur ein 65536tel davon nehmen.
--> wir können nur jede ca. 40.3. farbe nehmen.

--> passe einfach die Farben an den nächsten 40er schritt an.
between angels and insects

JPD

BeitragMi, Jul 26, 2006 16:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, dies währe dann die Variante, wenn keine Palette vorgegeben wird.

Meine Frage bezog sich darauf, wie ich ein Bild mit 24 Bit einer bestehenden Palette anpassen kann. Dithering oder Rasterung ist nicht notwendig, und wohl auch in diesem Fall zu schwierig.

Ich habe mir eine Methode ausgedacht. Es gibt doch diesen absoluten Farbwert, wird zum Beispiel bei writepixelfast x, y, Farbwert angewendet. Ist es mit diesem Farbwert möglich, ein Bild einer Palette anzupassen?

Gruß, Jan
 

Skulk

BeitragMi, Jul 26, 2006 16:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie wärs mit folgender Variante

du liest die Palette in den Speicher ein (z.b. dim)
du liest jeden Pixel einzeln aus.

Subttrahiere von den Palettenwerten den Pixelwert und merke dir den absoluten wert.
mache das für jede farbe in der palette.
nun suche den kleinsten wert heraus (die geringste differenz zum orginal farbwert) und speichere diesen im neuen bild ab.

natürlich musst du das für jede farbe machen
der "kleinste" wert setzt sich dann aus differenz R, differenz G und differenz B zusammen


ich kann dir nicht garantieren dass dies der perfekteste algorithmus ist, aber so könnte es eigentlich klappen

PS: Denkfehler vorbehalten Smile
War doesn't determine who's right,
war determines who's left...

JPD

BeitragMi, Jul 26, 2006 19:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, so funktionierts. Es ist sicher nicht die schnellste und beste Methode, aber Sie funktioniert.

Das Prinzip ist einfach. Es werden die 3 Farbwerte ausgelesen, die absolute Differenz zu den Paletteneinträgen berechnet und danach wird die niedrigste Differenz verwendet. Bei einem Bild von 256x256 Pixel braucht das Tool bei mir ca 1 Sekunde ...

Code: [AUSKLAPPEN]

;24 Bit umrechnen zu 256-Farben Palette
;26.07.2006
Graphics 640,480,32,2
SetBuffer BackBuffer()

;Palette laden
Dim pal(256)
LoadPalette("palette.act")
;Palette:
;RGBRGBRGBRGB ... (256 x RGB)


;Das Originalbild laden
original = LoadImage("color.bmp")




;##### Eigentliche Funktion


;Das zu modifizierende Bild laden
angepasst = LoadImage("color.bmp")

;Ein Feld anlegen, welches die Differenz eines Pixels zur Palettenfarbe speichert
Dim diff#(256)

;Buffer setzen und locken
SetBuffer ImageBuffer(angepasst)
LockBuffer ImageBuffer(angepasst)

;Schleife, um jedes Pixel abzugrassen
For y = 0 To ImageHeight(angepasst)
For x = 0 To ImageWidth(angepasst)

farbe = ReadPixelFast(x,y) ;Aktuelle Farbe ermitteln

For a = 0 To 255 ;Schleife 256 Durchgänge
;Farbdifferenzen zwischen R,G und B ermitteln
d_r = Abs( get_r(farbe) - get_r(pal(a)))
d_g = Abs( get_g(farbe) - get_g(pal(a)))
d_b = Abs( get_b(farbe) - get_b(pal(a)))
;Diese 3 Differenzen als einzige Gleitkommazahl wiedergeben
diff#(a) = Float(d_r + d_g + d_b) / 3.0
Next

ab# = diff#(0) ;Nun die kleinste Differenz ermitteln
kl = 0 ;Der kleinste Wert soll erstmal der Paletteneintrag 0 sein
For a = 0 To 255 ;Schleife 256 Durchgänge
If diff#(a) < ab# Then ;Wenn die jetzige Differenz kleiner ist, als eine Vorherige
ab# = diff#(a) ; ... ab# soll die Aktuelle Differenz sein
kl = a ; ... Der kleinste Wert ist Paletteneintrag a
EndIf
Next

WritePixel x,y,pal(kl)

Next
Next

UnlockBuffer ImageBuffer(angepasst)


;##### Eigentliche Funktion Ende






SetBuffer BackBuffer()
Repeat
Cls
If KeyHit(1) End
Text 10,10, "Original"
DrawBlock original,10,30
Text 300,10, "Angepasst"
DrawBlock angepasst,300,30
Delay 10
Flip
Forever
End


;Farbcode zu R
Function get_r(farbe)
wert = (farbe And $FF0000)/$10000
Return wert
End Function

;Farbcode zu G
Function get_g(farbe)
wert = (farbe And $FF00)/$100
Return wert
End Function

;Farbcode zu B
Function get_b(farbe)
wert = (farbe And $FF)
Return wert
End Function

;Umwandeln von RGB in Farbcode
Function rgb(r=0,g=0,b=0)
rgb = 255 * $1000000 + (r) * $10000 + (g) * $100 + (b)
Return rgb
End Function

;Palette laden (DIM-Feld pal(256) erforderlich
Function LoadPalette(file$)
temp = ReadFile(file$)
For run = 0 To 255
r = ReadByte(temp)
g = ReadByte(temp)
b = ReadByte(temp)
pal(run) = rgb(r,g,b)
Next
CloseFile(temp)
End Function



Viel Spass damit, mfg JPD Wink


PS: Die Palette kann ganz einfach in Photoshop oder ähnlichem als ACT gespeichert werden. Ich brauche diesen Code für ein Tool, welches Bitmaps wieder zurück in ein Spieleformat rechnet, das mit einer vorgegebenen 256-Farben-Palette arbeitet.
  • Zuletzt bearbeitet von JPD am Mi, Jul 26, 2006 20:31, insgesamt einmal bearbeitet

JPD

BeitragMi, Jul 26, 2006 20:06
Antworten mit Zitat
Benutzer-Profile anzeigen
PS: Vielleicht packe ich auch noch das Dithering Cool

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group