Converting an RGB image to 1 bit-per-pixel monochrome
Posted: Fri May 17, 2013 9:55 am
You can create the illusion of a half-tone transitions and display shades of gray.
Help PureBasic

Code:
Result of operation:
Normal conversion

Dithering Algorithm

Help PureBasic
Result of operation:When an image is saved using palettized depth ( 1, 4 or 8 ), the following flag is available for combination:
#PB_Image_FloydSteinberg: Apply a Floyd-Steinberg dithering.

Code:
Code: Select all
UseJPEGImageDecoder()
UsePNGImageDecoder()
;{ Windows
Enumeration
#Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
#Image_0
#Image_1
#TrackBar_2
#Button_3
#Button_4
#CheckBox_5
EndEnumeration
;}
;{ Images
Enumeration
#Image_Image_0
#Image_Image_1
EndEnumeration
;}
Macro Convert()
If GetGadgetState(#CheckBox_5)
If IsImage(0)
CopyImage(0, 1)
BlWiImg(1)
SetGadgetState(#Image_1, ImageID(1))
EndIf
Else
If IsImage(0)
CopyImage(0, 1)
BaWImg(1)
SetGadgetState(#Image_1, ImageID(1))
EndIf
EndIf
EndMacro
;- black-white
Procedure.l BaWImg(Img)
If Not IsImage(Img) : ProcedureReturn #False : EndIf
Gree=GetGadgetState(#TrackBar_2)
;Debug Gree
StartDrawing(ImageOutput(Img))
Width = ImageWidth(Img) - 1
Height = ImageHeight(Img) - 1
For y = 0 To Height
For x = 0 To Width
Pixel = Point(x, y)
If Pixel>RGB(Gree,Gree,Gree) ;
Plot(x, y, RGB(255,255,255))
Else
Plot(x, y,0)
EndIf
Next x
Next y
StopDrawing()
ProcedureReturn #True
EndProcedure
;-Dithering Algorithm
Procedure DitherFract(i.i , j.i )
Static.i DitherError
cc.i = Point(i, j)
cl.i=cc
rr.i=Red(cc): gg=Green(cc): bb=Blue(cc)
cc.i=(2*rr+3*gg+bb)/6 ; Or (299*rr+587*gg+114*bb)/1000;
cc_128 = GetGadgetState(#TrackBar_2);
cc_min = 10
If cc <= cc_128
cc = cc * (110 - cc_min) / cc_128 + cc_min
Else
cc = (cc - cc_128) * (255 - 146) / (255 - cc_128) + 146
EndIf
;
cc.i = cc - 128
DitherError = DitherError + cc * 32 / 31
If DitherError <= 0 Or cl<10
Plot (i, j, 0);RGB(0, 0, 0))
DitherError = DitherError + 128
Else
Plot (i, j, RGB(255, 255, 255))
DitherError = DitherError - (255 - 128)
EndIf
DitherError = DitherError * 31 / 32
EndProcedure
Procedure.l BlWiImg(Img)
StartDrawing(ImageOutput(Img))
Width = ImageWidth(Img) - 1
Height = ImageHeight(Img) - 1
For y = 0 To Height
For x = 0 To Width
DitherFract(x ,y )
Next
Next
StopDrawing()
EndProcedure
;}
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 550, 36, 1000, 550, "Converting an RGB image to 1 bit-per-pixel monochrome", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
ImageGadget(#Image_0, 10, 35, 480, 440, 0, #PB_Image_Border)
ImageGadget(#Image_1, 505, 35, 480, 440, 0, #PB_Image_Border)
TrackBarGadget(#TrackBar_2, 505, 490, 480, 25, 1, 255, #PB_TrackBar_Ticks):SetGadgetState(#TrackBar_2,128)
ButtonGadget(#Button_3, 175, 525, 120, 25, "Save in BMP 1 bpp")
ButtonGadget(#Button_4, 15, 5, 200, 20, "Load")
CheckBoxGadget(#CheckBox_5, 875, 515, 155, 25, "Dithering")
EndIf
EndProcedure
OpenWindow_Window_0()
;{- Event loop
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #CheckBox_5
Convert()
ElseIf EventGadget = #Image_1
ElseIf EventGadget = #TrackBar_2
Convert()
ElseIf EventGadget = #Button_3
If IsImage(1)
File$ = SaveFileRequester("Please choose file to save", "","",0)
SaveImage(1, File$ , #PB_ImagePlugin_BMP, 0, 1)
EndIf
ElseIf EventGadget = #Button_4
Pattern$ = "Image |*.bmp;*.jpg;*.png"
Filename$ = OpenFileRequester("","",Pattern$,0)
If Filename$>""
If LoadImage(0, Filename$)
Repeat
If ImageWidth(0)>480 Or ImageHeight(0)>440:ResizeImage(0,ImageWidth(0)/1.1, ImageHeight(0)/1.1):EndIf
Until ImageHeight(0)<440 And ImageWidth(0)<480
SetGadgetState(#Image_0, ImageID(0))
Convert()
EndIf
EndIf
EndIf
; ////////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
;
;}
Normal conversion

Dithering Algorithm
