| MENU
- Intro
- DUPLICATE
- SETTING
THE IMAGE OF
A MEMBER
- PRE-STORING
RECT VALUES
- DRAWING
TO THE STAGE
Optimizing
Imaging Lingo:
Provided by Zevan Renteren
A few rules that will speed up your imaging lingo projects.
This tutorial assumes that you have knowledge of basic imaging lingo.
We're going to be doing speed tests throughout this tutorial. For this reason
I am using my slower computer with an 866 mhz processor. If your computer is
extremly fast you may not see the speed difference. If this is the case, just
throw in a repeat loop or alter the number of times we are repeating a specific
action and you'll see the result.
DUPLICATE
One of the more important things to do when using imaging lingo is to use duplicate()
with cast member image objects. If you want to make changes to a cast members
image object, make a duplicate and store it in a variable, make your alterations
and then copy it back. Working directly with a members image is slower than working
with an image object in ram.
Here is a simple test that will display the difference in milleseconds. Create
a bitmap member and name it "myImageMember". Run this lingo on a framescript:
property myImage
property _start,_end
on beginSprite me
-- with duplicate
_start= the milliseconds
myImage = member("myImageMember").image.duplicate()
repeat with i
= 0 to 1200
myImage.setPixel(random(50,50),random(50,50),rgb(random(100),0,0))
end repeat
_end= the milliseconds
put "with
duplicate", _end - _start
-- without duplicate
_start= the milliseconds
myImage = member("myImageMember").image
repeat with i
= 0 to 1200
myImage.setPixel(random(50,50),random(50,50),rgb(random(100),0,0))
end repeat
_end= the milliseconds
put "without
duplicate", _end - _start
end
On my 866 mhz processor, the results are:
-- "with duplicate " 8
-- "without duplicate " 19
SETTING THE IMAGE OF A MEMBER
When setting the image of a member, its faster to use copyPixels than to set
it using the member's image property:
Create a bitmap member and name it "myImageMember". Run this lingo on a framescript:
property myImage
property _start,_end
on beginSprite me
myImage=image(100,100,32)
-- create a gradient type graphic
repeat with _x
= 0 to 100
repeat with _y
= 0 to 100
myImage.setPixel(_x,_y,rgb(_x,_y,0))
end repeat
end repeat
-- using copyPixels
_start= the milliseconds
repeat with i
= 0 to 100
myImage.copyPixels(myImage,rect(0,0,100,100),rect(0,0,100,100))
end repeat
_end= the milliseconds
put "with
copyPixels ", _end - _start
-- using image property
_start= the milliseconds
repeat with i
= 0 to 100
member("myImageMember").image =
myImage
end repeat
_end= the milliseconds
put "without
copyPixels ", _end - _start
end
Here are the results:
-- "with copyPixels " 5
-- "without copyPixels " 16
PRE-STORING RECT VALUES
Instead of continually reading the rect property of a member, it makes sense
to either hard code the rect value or store it in a variable. So:
property myImage
on beginSprite me
myImage=member("myImageMember").image.duplicate()
end
on prepareFrame me
(the stage).image.copyPixels(myImage,myImage.rect,myImage.rect)
end
would become:
property myImage, myImageRect
on beginSprite me
myImage=member("myImageMember").image.duplicate()
myImageRect = myImage.rect
end
on prepareFrame me
(the stage).image.copyPixels(myImage,myImageRect,myImageRect)
end
Speed Test:
-- with pre-storing
on prepareFrame me
_start = the milliseconds
repeat with i = 0 to 2000
(the stage).image.copyPixels(myImage,myImageRect,myImageRect)
end repeat
_end = the milliseconds
put _end - _start
end
-- without pre-storing
on prepareFrame me
_start = the milliseconds
repeat with i = 0 to 2000
(the stage).image.copyPixels(myImage,myImage.rect,myImageRect.rect)
end repeat
_end = the milliseconds
put _end - _start
end
The one with pre-storing takes 124 milliseconds and the one with out
pre-storing takes 139. This isn't a huge difference, but it certainly doesn't
hurt to implement it.
DRAWING TO THE STAGE
Something I see a good deal in imaging lingo source is an "imageBuffer" image
object. Lingo programmers draw everything to this image object and then copy
it to the stage. This is entirely uneccessary. There are times when it might
make sense to create buffers, but it is definately not needed in all cases. I
guess this tendancy comes from working with java or c/c++? Whatever the reason,
its much faster in director to draw directly to the stage:
SLOW:
property myImage, buffer
property stageRect,myImageRect
property _start, _end
on beginSprite me
myImage=member("myImageMember").image.duplicate()
-- pre-store rects
myImageRect = myImage.rect
stageRect = (the stage).image.rect
-- create image buffer
buffer=image((the stage).image.width,(the stage).image.height,32)
end
on prepareFrame me
_start = the milliseconds
-- create a quick grid
repeat with _x in [0,100,200,300]
repeat with _y in [0,100,200,300]
-- draw to buffer
buffer.copyPixels(myImage,rect(_x,_y,100+_x,100+_y),myImageRect)
end repeat
end repeat
-- draw buffer to stage
(the stage).image.copyPixels(buffer,stageRect,stageRect)
_end = the milliseconds
put _end - _start
end
You'll see how long each frame is taking to draw in the message window.
On my computer I see:
-- 12
-- 11
-- 13
Now, if we get rid of the extra step of drawing to a buffer we see a drastic
speed improvement:
FAST:
property myImage
property stageRect,myImageRect
property _start, _end
on beginSprite me
myImage=member("myImageMember").image.duplicate()
-- pre-store rects
myImageRect = myImage.rect
stageRect = (the stage).image.rect
end
on prepareFrame me
_start = the milliseconds
-- create a quick grid
repeat with _x in [0,100,200,300]
repeat with _y in [0,100,200,300]
-- draw to stage
(the stage).image.copyPixels(myImage,rect(_x,_y,100+_x,100+_y),myImageRect)
end repeat
end repeat
_end = the milliseconds
put _end - _start
end
My message window now shows:
-- 3
-- 3
-- 3
-- 3
-- 3
-- 4
-- 3
Wow. This is a huge difference.
Thats about it. Of course, its not always neccessary to abide by these rules.
I don't usually pre-store rects when I am setting up my image objects and sometimes
I won't develop a project with all these optimizations in mind. I'll create the
project and then go back and optimize where I feel its necessary. If anyone has
additional imaging lingo optimizations, shoot me an e-mail and I'll ad them to
this tutorial.
|