Atkinson dither algorithm & 'for each' loop
Alejandro Tejada
capellan2000 at gmail.com
Fri Oct 13 05:53:51 EDT 2017
After reading Mark Waddingham explanation, now i am using a sequential
ordered array for this handler. Check this much shorter and faster version:
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
put the width of img "Image" into tImageWidth
put the height of img "Image" into tImageHeight
put the number of chars of tVar into tImgPixels
if existence(sb the "ThresholdDither") then
put thumbPos of sb the "ThresholdDither" into tThreshold
else
put 127 into tThreshold
end if
put numtochar(0) & numtochar(255) & numtochar(255) & numtochar(255) into
tWP
put numtochar(0) & numtochar(0) & numtochar(0) & numtochar(0) into tBP
put ((tImageWidth * tImageHeight) - tImageWidth) into tHW
put ImgToArrayNum(ImgToCh(tVar,1)) into tArray2
put 0 into tPixelCounter
put tImgPixels/4 into tPixels
repeat tPixels
add 1 to tPixelCounter
put tPixelCounter into tPixelPosition
put tArray2[tPixelCounter] into tOldPixelValue
if round(tOldPixelValue) <= tThreshold then
put 0 into tNewPixelValue
put tBP after fldhexa8
else
put 255 into tNewPixelValue
put tWP after fldhexa8
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
if tPixelPosition mod tImageWidth <> 0 then
-- pixel position is less than image width
put tPixelCounter + 1 into tNewKey
put (tDifusionError) + tArray2[tNewKey] into tArray2[tNewKey]
if tPixelPosition mod (tImageWidth - 1) <> 0 then
-- pixel position is less than image width - 1
put tPixelCounter + 2 into tNewKey
put tDifusionError + tArray2[tNewKey] into tArray2[tNewKey]
end if
end if
if tPixelPosition <= tHW then -- ((tImageWidth * tImageHeight) -
tImageWidth)
-- pixel position is not in the last line of the image
if tPixelPosition mod tImageWidth <> 1 then
-- pixel position is not the first pixel in any line of the
image
put (tPixelPosition + tImageWidth - 1) into tNewKey
put (tDifusionError) + tArray2[tNewKey] into tArray2[tNewKey]
end if
put (tPixelPosition + tImageWidth) into tNewKey
put (tDifusionError) + tArray2[tNewKey] into tArray2[tNewKey]
if tPixelPosition mod tImageWidth <> 0 then
-- pixel position is less than image width
put (tPixelPosition + tImageWidth + 1) into tNewKey
put (tDifusionError) + tArray2[tNewKey] into tArray2[tNewKey]
end if
if tPixelPosition <= (tImageWidth * tImageHeight) - (tImageWidth *
2) then
-- pixel position is less than image width - 1
put (tPixelPosition + tImageWidth * 2) into tNewKey
put (tDifusionError) + tArray2[tNewKey] into tArray2[tNewKey]
end if
end if
end repeat
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 fldhexa8
set the alphaData of it to tAlphaData
put the millisecs - startTime && "milliseconds to create Atkinson Dither
from image's single channel"
end mouseUp
Function ImgToArrayNum vImageData
-- This function converts binary imagedata to
-- integer numbers from 0 to 255 into
-- an array.
-- vImageData is a single color channel
-- stored as binary imagedata.
put empty into tResult
put 0 into tCounter
repeat for each char K in vImageData
add 1 to tCounter
put chartonum(K) into tResult[tCounter]
end repeat
return tResult
end ImgToArrayNum
Function ImgToCh tImageData tChannel
-- This function returns binary data.
--
-- tImageData is unmodified original imagedata of image
-- with 4 chars for each pixel: 1 alphadata and 3 color channels.
--
-- tChannel is a number from 1 to 3:
-- 1 is red channel, 2 is green channel and 3 is blue channel
put tImageData into tempVar
delete char 1 to tChannel of tempVar
-- the first char of the imagedata is part
-- of the alphadata or maskdata, so when
-- we delete char 1, the next char is part
-- from red channel... if we delete 2 first
-- chars, then next char is green channel
-- if we delete 3 first chars, then we get
-- the blue channel
repeat until tempVar is empty
put char 1 of tempVar after tResult
delete char 1 to 4 of tempVar
end repeat
return tResult
end ImgToCh
Have a nice weekend!
Al
More information about the use-livecode
mailing list