Dithering techniques
Posted: Fri Apr 04, 2003 6:09 am
Restored from previous forum. Originally posted by El_Choni.
Along with ordered dither and Floyd-Steinberg dithering, for which you'll find examples in ImageViewer (available at Paul's site http://www.reelmediaproductions.pb/pb), there are more dithering techniques. Here are two examples of those. Both use a Hilbert curve, this is, a line which passes through all points whithout intersecting itself. They're used here for 32 to 1 bit translation.
Yes, I know, not too much useful, but fun to play with. You'll find them in next ImageViewer release.
Have a nice day,
El_Choni
Along with ordered dither and Floyd-Steinberg dithering, for which you'll find examples in ImageViewer (available at Paul's site http://www.reelmediaproductions.pb/pb), there are more dithering techniques. Here are two examples of those. Both use a Hilbert curve, this is, a line which passes through all points whithout intersecting itself. They're used here for 32 to 1 bit translation.
Yes, I know, not too much useful, but fun to play with. You'll find them in next ImageViewer release.
Code: Select all
; Hilbert-Peano dithering
Declare Max(a, b)
Declare Log2(value)
#NONE = 0
#UP = 1
#LEFT = 2
#DOWN = 3
#RIGHT = 4
#SIZE = 16
#MAX = 16
Global cur_x, cur_y, img_width, img_height, img_ptr, error
Procedure dither_pixel(*pixel)
px = PeekL(*pixel)
px = ((px&$FF)+((px>> &$FF)+((px>>16)&$FF))/3
pvalue = px+error
If pvalue>=128
pvalue = 255
Else
pvalue = 0
EndIf
error+px-pvalue
If error>255:error-255:EndIf
PokeL(*pixel, pvalue|(pvalue=0 And cur_x=0 And cur_ya:a = b:EndIf
ProcedureReturn a
EndProcedure
Procedure Log2(value)
result = 0
While value>1
value>>1
result+1
Wend
ProcedureReturn result
EndProcedure
And Riemersma, supposed to enhance the previous technic:
; Riemersma dithering
Declare Max(a, b)
Declare Log2(value)
Declare.f Exp(value.f)
#E_NUMBER = 2.71828182 ; 2.718281819
#NONE = 0
#UP = 1
#LEFT = 2
#DOWN = 3
#RIGHT = 4
#SIZE = 16
#MAX = 16
Global cur_x, cur_y, img_width, img_height, img_ptr
Dim weights.f(#SIZE)
Dim error.f(#SIZE)
Procedure init_weights(size, max)
m.f = Exp(Log(max)/(size-1))
v.f = 1.0
For i=0 To size-1
weights(i) = v+0.5
v*m
Next i
EndProcedure
Procedure dither_pixel(*pixel)
err = 0
For i=0 To #SIZE-1
err+(error(i)*weights(i))
Next i
px = PeekL(*pixel)
px = ((px&$FF)+((px>> &$FF)+((px>>16)&$FF))/3
pvalue = px+(err/#MAX)
If pvalue>=128
pvalue = 255
Else
pvalue = 0
EndIf
CopyMemory(error()+4, error(), (#SIZE-1)*4)
error(#SIZE-1) = px-pvalue
PokeL(*pixel, pvalue|(pvalue=0 And cur_x=0 And cur_ya:a = b:EndIf
ProcedureReturn a
EndProcedure
Procedure Log2(value)
result = 0
While value>1
value>>1
result+1
Wend
ProcedureReturn result
EndProcedure
Procedure.f Exp(value.f)
ProcedureReturn Pow(#E_NUMBER, value)
EndProcedure
Have a nice day,
El_Choni