Atkinson dither algorithm

Alejandro Tejada capellan2000 at gmail.com
Sat Oct 7 01:52:20 EDT 2017


Hi All,

I am stuck trying to make this code for Bill Atkinson
dithering algorithm much more faster.
Any ways to speed this code?
Follow the recipe and watch out for lines broken
by mail character length limit.

Recipe:

1) Import an small image (200x200 pixels) and
name it as "Image" (you could import a small
transparent png or a small jpg image)

2) Optionally, create a scrollbar type slider
with a range between 0 and 255.
Set the name of this scrollbar as "ThresholdDither"
and move the slider to 127 or 0 or 255.

3) Paste the following script in a button and
click on it to run this code:

on mouseUp

   put the millisecs into startTime
   set the cursor to busy

   put the alphadata of img "Image" into tAlphaData
   put the imagedata of img "Image" into tVar
   -- img "Image" could be a grayscale image
   -- where all 3 channels: Red, Green, Blue
   -- are identical or a color image where only
   -- the red channel is used

   delete char 1 of tVar
   -- the first char of the imagedata is part
   -- of the alphadata or maskdata
   repeat with i = 1 to length(tVar) step 4
      put chartonum(char i of tVar) & space after fldhex
   end repeat
   delete last char of fldhex -- a space
   -- fldhex now contains a single channel of the RGB image
   -- converted to numbers between 0 and 255

   put the number of words of fldhex into lenghtofldhex
   put the width of img "Image" into tImageWidth
   put the height of img "Image" into tImageHeight

   repeat with i = 1 to lenghtofldhex step tImageWidth
   -- We need as many words per line, as pixels contains
   -- the image width (because each pixel is represented
   -- by a word and this word is number between 0 and 255)

   put word i to ( i + ((tImageWidth) - 1)) of fldhex & cr after fldhexa2
   end repeat

   put empty into fldhex
   delete last char of fldhexa2
   -- deleting the last cr character

   put the number of lines of fldhexa2 into sYsize
   put the number of words of line 1 of fldhexa2 into sXsize

   // get the scrollbar value
   -- tThreshold is a value between 0 and 255
   if existence(sb the "ThresholdDither") then
   put thumbPos of sb the "ThresholdDither" into tThreshold
   else
   put 127 into tThreshold
   end if

   repeat with tY = 1 to sYsize
      repeat with tX = 1 to sXsize

         put tX into tPixelPosition

         put word (tPixelPosition) of line tY of fldhexa2 into
tOldPixelValue

         if round(tOldPixelValue) <= tThreshold then
            put 0 into tNewPixelValue
         else
            put 255 into tNewPixelValue
         end if

         put (tOldPixelValue - tNewPixelValue)/8 into tDifusionError

         -- Atkinson dither add the diffusion error
         -- to 6 adjacent pixels
         --         x o o
         --      o o o
         --         o

         put tNewPixelValue & space after fldhexa3


            if tPixelPosition < sXsize then
               put tDifusionError + word (tPixelPosition + 1) of line tY of
fldhexa2 into word (tPixelPosition + 1) of line tY of fldhexa2


              if tPixelPosition < (sXsize-1) then
                  put tDifusionError + word (tPixelPosition + 2) of line tY
of fldhexa2 into word (tPixelPosition + 2) of line tY of fldhexa2
               end if


            end if


            if tY < sYsize then


               if tPixelPosition > 1 then
                  put tDifusionError + word (tPixelPosition - 1) of line tY
+ 1 of fldhexa2 into word (tPixelPosition - 1) of line tY + 1 of fldhexa2
               end if


               put tDifusionError + word (tPixelPosition) of line tY + 1 of
fldhexa2 into word (tPixelPosition) of line tY + 1 of fldhexa2


               if tPixelPosition < sXsize then
                  put tDifusionError + word (tPixelPosition + 1)  of line
tY + 1 of fldhexa2 into word (tPixelPosition + 1) of line tY + 1 of fldhexa2
               end if


               if tY < (sYsize - 1) then
                  put tDifusionError + word (tPixelPosition) of line tY + 2
of fldhexa2 into word (tPixelPosition) of line tY + 2 of fldhexa2
               end if


            end if

      end repeat
   end repeat

   replace "0" with "00" in fldhexa3
   replace "255" with "FF" in fldhexa3

   repeat with i = 1 to the number of words of fldhexa3
      put 00 & word i of fldhexa3 & word i of fldhexa3 & word i of fldhexa3
after tVar2
   end repeat
   put binaryEncode("H*",tVar2) into tVar3

   create img
   set the height of it to the height of img "Image"
   set the width of it to the width of img "Image"
   set the imagedata of it to tVar3
   set the alphaData of it to tAlphaData

   put the millisecs - startTime && "milliseconds to create Atkinson Dither"

end mouseUp

Thanks in advance!
Al



More information about the use-livecode mailing list