Hi Mike,
That is a very nice update. With an excellent speed increase.
I hope you do not mind if I suggest some possible variants.
You now use styledText as a way to load fields. I would have thought to also use styledText to save the "images" to a file.
If you make an array of the styledText arrays and arrayEncode + compress that array you have an increase in file size but you can streamline your loading and display of the animation.
As a proof of principle I made two button:
Button 1 to save styledText from the loaded image for animation:
Code: Select all
on mouseUp
local tFrames, tOneFrame, tFrameName, tFrameShort, tFrameList
local tAllStyledTextA, tCounter, tImgData, tLson, tLength, tStackPath, tResult
put "Frame" into tFrameShort
repeat with i = 1 to 12
put tFrameShort & i & cr after tFrameList
end repeat
delete char -1 of tFrameList
repeat for each line aFrame in tFrameList
add 1 to tCounter
put imageToAsciiData(aFrame) into tAllStyledTextA[tCounter]
end repeat
put arrayEncode(tAllStyledTextA) into tLson
put compress (tLSon) into tLson
put the length of tLson into tLength
put the long name of this stack into tStackPath
set the itemDelimiter to slash
put item 2 to -2 of tStackPath into tStackPath
set the itemDelimiter to comma
put slash before tStackPath
put slash & "test.lson.gz" after tStackPath
put tLson into url("binfile:" & tStackPath)
put the result into tResult
end mouseUp
constant kBlockChar = "█"
constant kDotChar = "•"
function imageToAsciiData pImageName
local tImageData, tBytesPerPixel, tLineSize, tImageWidth, tImageHeight, tDisplayChar
-- Get the image data
put the imageData of image pImageName into tImageData
put the width of image pImageName into tImageWidth
put the height of image pImageName into tImageHeight
-- Each pixel is represented by 4 bytes in imageData
put 4 into tBytesPerPixel
-- Calculate line size
put tImageWidth * tBytesPerPixel into tLineSize
put kBlockChar into tDisplayChar
local tBytePosition, tLineNumber, tRunsNum, tStyleA, tCurrRGB, tPrevRGB, tPathToStyle
local tRed, tGreen, tBlue
put "style,textColor" into tPathToStyle
split tPathToStyle by comma
-- Loop through each pixel
repeat with y = 0 to tImageHeight - 1
put y + 1 into tLineNumber
put 0 into tRunsNum
put empty into tPrevRGB
repeat with x = 0 to tImageWidth - 1
-- Calculate the byte position in the imageData
put (y * tLineSize) + (x * tBytesPerPixel) + 1 into tBytePosition
-- Extract RGB values
-- Byte 1: Ignored (tBytePosition)
-- Byte 2: Red (tBytePosition + 1)
-- Byte 3: Green (tBytePosition + 2)
-- Byte 4: Blue (tBytePosition + 3)
put charToNum(char tBytePosition + 1 of tImageData) into tRed
put charToNum(char tBytePosition + 2 of tImageData) into tGreen
put charToNum(char tBytePosition + 3 of tImageData) into tBlue
put tRed & comma & tGreen & comma & tBlue into tCurrRGB
if tCurrRGB <> tPrevRGB then
add 1 to tRunsNum
put tCurrRGB into tStyleA[tLineNumber]["runs"][tRunsNum][tPathToStyle]
put tDisplayChar after tStyleA[tLineNumber]["runs"][tRunsNum]["Text"]
put tCurrRGB into tPrevRGB
else
put tDisplayChar after tStyleA[tLineNumber]["runs"][tRunsNum]["Text"]
end if
end repeat
end repeat
return tStyleA
end imageToAsciiData
Button 2 for loading the saved Array
Code: Select all
global gLsonDataA
on mouseUp
local tData, tFilePath
answer file "choose lson.gz file"
put it into tFilePath
if tFilePath is empty then exit mouseUp
put url("binfile:" & tFilePath) into tData
put decompress(tData) into tData
put arrayDecode(tData) into tData
put tData into gLsonDataA
end mouseUp
Note the global gLsonDataA
I changed your button "Start Animation" on the card script after adding global gLsonDataA -- stores styledText of the images to the card
Code: Select all
on startAnimation
put kBlockChar into gDisplayChar
if gAnimationRunning then exit startAnimation ## avoid start when already running
put true into gAnimationRunning
put 0 into gCurrentFrame
animateFrames
end startAnimation
on animateFrames
local tStyledA, tSpeed, tDelay
if not gAnimationRunning then exit animateFrames
add 1 to gCurrentFrame
put gLsonDataA[gCurrentFrame] into tStyledA
set the styledText field "TextArtField" of me to tStyledA
local tNumElements
put the number of elements of gLsonDataA into tNumElements
if gCurrentFrame = the number of elements of gLsonDataA then put 0 into gCurrentFrame
if there is a scrollbar "SpeedControl" then
put the thumbPosition of scrollbar "SpeedControl" into tSpeed
-- Convert speed to milliseconds (e.g., scale of 1 to 100 corresponds to 1000ms to 10ms)
put 101 - tSpeed into tDelay
put tDelay * 10 into tDelay -- Convert to milliseconds
else
put 100 into tDelay -- Default delay if scrollbar doesn't exist
end if
-- Schedule the next frame
send "animateFrames" to me in tDelay milliseconds
end animateFrames
Those two handlers will start the animation by setting the styledText of the field.
It is at least as fast as your current solution but considerably easier to maintain.
If you want to test this put those two handlers above the respective handler of the same name and LC will use them. You do not even have to block the current handlers of the same name because LC only "sees" the first occurence of a handler.
Your datc format for the 12 images is 153 Kb whereas the styledText array is 190 Kb. I think that is ok for simplifying the code.
Of course this is just a suggestion, it works very well as it is.
Kind regards
Bernd