Author Topic: a 16-bit dither for images.  (Read 1869 times)

Offline sf-in-sf

  • Mr. Drawsprite
  • **
  • Posts: 93
  • Artist F.P. Brixey
    • View Profile
    • My computed art project
a 16-bit dither for images.
« on: 2013-Mar-05 »

Hi everyone!
This program will nicely dither your images, for mobile apps. Enjoy!
It works in the free demo version of pure basic, a nice IDE though not suited for mobile devices.
Please read and season to taste.

Code: (glbasic) [Select]
; Dither to RGB565 by Artist F.P.Brixey
;Please note: source file must be 32bit PNG with alpha.
;No alpha chanel produces a black image.
;If so, please process your source image:
;GIMP->Layer->transparency->add alpha chanel

InitSprite() : InitKeyboard()
Procedure.c rand_()
    ;write here your favorite hand-crafted chaos generator
  a.c= Random(1)
  a= Random(787) ; (let's shuffle!)
  a=(Random(9955) & $00ff)
  ProcedureReturn a ; type is char, unsigned byte please.
EndProcedure

Procedure.c from8to6(n.c) ; c is char, unsigned byte.
  ; We want to chop and dither the 2 LSB
  ;ProcedureReturn (n & $00fc) ; for special effects?
  n2.c= n & ($00ff-$0003)
  If n2 <$00fc And n & $0003 > rand_() & $0003
    n2=n2+$0004
  EndIf
  ProcedureReturn n2
EndProcedure

Procedure.c from8to5(n.c)
  ; We want to chop and dither the 3 LSB
  ; You get the traditional careless banding by adding here:
  ;ProcedureReturn (n & $00f8) ; for special effects?
  n2.c= n & ($00ff-$0007)
  If n2 <$00f8 And n & $0007 > rand_() & $0007
    n2=n2+$0008
  EndIf
  ProcedureReturn n2
EndProcedure

Procedure show(ima)
scrnum=OpenScreen(1024,768,32,"")
StartDrawing(ScreenOutput())
DrawAlphaImage(ImageID(ima),0,0)
;Box(20,20,40,20,RGB(122,122,255))
StopDrawing()
FlipBuffers()
Repeat
  Delay(80) : ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen() ; was a quick check
EndProcedure

sourcename$=OpenFileRequester("Open a source image (PNG format)","","*.*", 0)
UsePNGImageDecoder()
imnum_src=LoadImage(#PB_Any,sourcename$)
; BMP is default (leave the last argument empty). for other formats, use
;UseJPEGImageDecoder() UseJPEG2000ImageDecoder() UsePNGImageDecoder()
;UseTIFFImageDecoder() UseTGAImageDecoder()

imW=ImageWidth(imnum_src)
imH=ImageHeight(imnum_src)
If imnum_src =0 : MessageRequester ("Problem","Image is not loaded.") : End
EndIf

;show(imnum_src) ; Press escape
imnum_target = CreateImage(#PB_Any,imW,imH,32)

For j=0 To imH-1
  For i=0 To imW-1
    StartDrawing(ImageOutput(imnum_src))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Rp=Red(Point(i,j))
    Gp=Green(Point(i,j))
    Bp=Blue(Point(i,j))
    Ap=Alpha(Point(i,j))
    ; alpha remains unchanged. Up to you.
    StopDrawing()
   
    rr=from8to5(Rp)
    gg=from8to6(Gp)
    bb=from8to5(Bp)
   
    StartDrawing(ImageOutput(imnum_target))
    DrawingMode(#PB_2DDrawing_AllChannels)   
    Plot(i,j,RGBA(rr,gg,bb,Ap)) ; with undithered alpha.
    StopDrawing()
  Next
Next


target$=sourcename$+"_dith565.png" ; change it freely.
; possibly: saveimagerequester(...

UsePNGImageEncoder()
s_i=SaveImage(imnum_target,target$, #PB_ImagePlugin_PNG,0,32) ;
    ;file format is still 32 bits RGBA.
 
If s_i <>0
  i=MessageRequester("Right", "Image was saved o.k.",#PB_MessageRequester_Ok )
Else
  i=MessageRequester("Sorry", "Image is not saved.",#PB_MessageRequester_Ok )
  End
EndIf

;show(imnum_target) ;now check the result. Reclaim your freedom by pressing 'escape'.
End

On the day the atom is a cube I will start believing in the square pixel.

Offline erico

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 4310
    • View Profile
    • Portfolio
Re: a 16-bit dither for images.
« Reply #1 on: 2013-Mar-05 »
Oh well, I havenĀ“t tried, but a little while tried dither fade things...similar to Card Clash SNKvsCAP.
This is the patterns I made, I hope it has anything to do with the post and helps. :-[