![]() a) original lena image |
![]() b) halftoning by ordered dither with a 2x2 pattern |
|---|---|
![]() c) halftoning along a fractal path |
![]() d) halftoning along a fractal path with corrected greyvalues |
![]() e) halftoning by ordered dither with transition smoothing larger image as pure HTML (374kB) |
![]() f) halftoning by ordered dither with pattern orientation by hilbert curve and transition smoothing larger image as pure HTML (469kB) |
![]() original grey scale ramp image |
![]() halftoning by algorithm used in image b) |
![]() halftoning by algorithm used in image c) |
![]() halftoning by algorithm used in image d) |
![]() halftoning by algorithm used in image e) |
![]() halftoning by algorithm used in image f) |
Dim ccStrP, ccStr0, ccStr1
Dim ccStr(4)
ccStrP = Array("II", "I.", "I ", ". ", " ")
ccStr0 = Array("II", "I'", ".'", ". ", " ")
ccStr1 = Array("II", "I.", "'.", "' ", " ")
ccStr(0) = Array("II", "I.", "I ", "' ", " ")
ccStr(1) = Array("II", "'I", "''", "' ", " ")
ccStr(2) = Array("II", "'I", " I", " .", " ")
ccStr(3) = Array("II", "I.", "..", " .", " ")
'...some lines have been erased here
cc = (2 * rr + 3 * gg + bb) 'used weights for red green and blue
Select Case BWEncoding
Case 0: '-----------SEE IMAGE b)------------------
cc = cc \ 308 'cc=0, 1, 2, 3, 4
iiHTML = iiHTML & ccStrP(cc)
Case 1: '-----------SEE IMAGE e)------------------
cc = cc + ((xx + yy) Mod 2) * 192 - 96 'smoothing
If cc < 0 Then cc = 0
cc = cc \ 308 'cc=0, 1, 2, 3, 4
If cc > 4 Then cc = 4
If (xx + yy) Mod 2 = 0 Then
iiHTML = iiHTML & ccStr0(cc)
Else
iiHTML = iiHTML & ccStr1(cc)
End If
Case 2: '-----------SEE IMAGE f)------------------
cc = cc + ((xx + yy) Mod 2) * 192 - 96 'smoothing
If cc < 0 Then cc = 0
cc = cc \ 308 'c=0, 1, 2, 3, 4
If cc > 4 Then cc = 4
hh_Shape = GetHilbertShape(xx, yy)
iiHTML = iiHTML & ccStr(hh_Shape)(cc)
End Select
'The function GetHilbertshape(i, j) returns 0, 1, 2 or 3, which represents the
'orientation of a hilbert curve of a size 2^(2*n) at pixel position (i, j)
'see code below:
------------------------------------------------------------------
Function GetHilbertShape(aii As Integer, ajj As Integer) As Integer
Dim ss, ii, jj
ii = 4 * aii + ajj 'coordinate trafo to get rid of artifacts
jj = 4 * ajj + aii 'try out other combinations too!
ss = 1
While ((ii >= ss) Or (jj >= ss))
ss = ss * 4
Wend
GetHilbertShape = GetHilbertShapeEven(ii, jj, ss, 0)
'GetHilbertShape = Int((4 * Rnd)) 'check out a random distribution
End Function
------------------------------------------------------------------
Function GetHilbertShapeEven(ByVal axx As Integer, ByVal ayy As Integer, ByVal asize As Integer, ByVal arot As Integer) As Integer
If asize = 1 Then
GetHilbertShapeEven = arot Mod 4
Exit Function
End If
Dim xx, yy, size2, rot
xx = axx: yy = ayy: size2 = asize \ 2: rot = arot
If (yy < size2) Then
If (xx < size2) Then
GetHilbertShapeEven = GetHilbertShapeOdd(xx, yy, size2, rot)
Else
GetHilbertShapeEven = GetHilbertShapeOdd(2 * size2 - 1 - xx, size2 - 1 - yy, size2, rot + 2)
End If
Else
If (xx < size2) Then
GetHilbertShapeEven = GetHilbertShapeOdd(yy - size2, size2 - 1 - xx, size2, rot + 3)
Else
GetHilbertShapeEven = GetHilbertShapeOdd(yy - size2, 2 * size2 - 1 - xx, size2, rot + 3)
End If
End If
End Function
----------------------------------------------------------------------
Function GetHilbertShapeOdd(ByVal axx As Integer, ByVal ayy As Integer, ByVal asize As Integer, ByVal arot As Integer) As Integer
Dim xx, yy, size2, rot
xx = axx: yy = ayy: size2 = asize / 2: rot = arot
If (yy < size2) Then
If (xx < size2) Then
GetHilbertShapeOdd = GetHilbertShapeEven(xx, yy, size2, rot)
Else
GetHilbertShapeOdd = GetHilbertShapeEven(size2 - 1 - yy, xx - size2, size2, rot + 1)
End If
Else
If (xx < size2) Then
GetHilbertShapeOdd = GetHilbertShapeEven(size2 - 1 - xx, 2 * size2 - 1 - yy, size2, rot + 2)
Else
GetHilbertShapeOdd = GetHilbertShapeEven(2 * size2 - 1 - yy, xx - size2, size2, rot + 1)
End If
End If
End Function
![]() | The Images c) and d) have been generated by walking on this fractal spacefilling curve and applying the following halftoning algorithm: |
|---|
Sub DitherFract(ByVal i As Integer, ByVal j As Integer)
Dim rr As Integer
Dim gg As Integer
Dim bb As Integer
Dim cc As Long
' Dim cc_128 As Long
' Dim cc_min As Long
' cc_128 = 160
' cc_min = 10
If ((i <= imax) And (j <= jmax)) Then
cc = Pic.Point(i, j)
Long2RGB cc, rr, gg, bb
cc = (2 * rr + 3 * gg + bb) \ 6
' If cc <= cc_128 Then
' cc = cc * (110 - cc_min) \ cc_128 + cc_min
' Else
' cc = (cc - cc_128) * (255 - 146) \ (255 - cc_128) + 146
' End If
cc = cc - 128
DitherError = DitherError + CInt(cc) * 32 \ 31
If DitherErro <= 0 Then
Pic.PSet (i, j), RGB(0, 0, 0)
DitherError = DitherError + 128
Else
Pic.PSet (i, j), RGB(255, 255, 255)
DitherError = DitherError - (255 - 128)
End If
End If
DitherError = DitherError * 31 \ 32
End Sub
![]() color error minimal f=1 |
![]() intermediate f=3/4 |
![]() spatial error minimal f=0 |
| compare with alg. e) (44kB) and alg. f) (56kB) (both as pure HTML pictures) | ||
| avg. distance when walking | 1 Pixel | 2 Pixel | 3 Pixel | 4 Pixel | |
|---|---|---|---|---|---|
![]() | 1: 1/1 avg: 1 | 2: 1/1 avg: 2 | 3: 1/1 avg: 3 | 4: 1/1 avg: 4 | LOSER |
![]() | 1: 1/1 avg: 1 | sqrt(2): 2/3 2: 1/3 avg: 1.61 | 1: 6/27 sqrt(5): 20/27 3: 1/27 avg: 1.99 | sqrt(2): 5/27 2: 12/27 sqrt(8): 7/27 sqrt(10): 3/27 avg: 2.23 | second winner |
![]() | 1: 1/1 avg: 1 | sqrt(2): 4/5 2: 1/5 avg: 1.53 | 1: 19/60 sqrt(5): 40/60 3: 1/60 avg: 1.86 | sqrt(2): 1/5 2: 3/5 sqrt(10): 1/5 avg: 2.12 | WINNER |