# Atkinson dither algorithm

```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 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
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
--         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

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

end mouseUp