[plt-scheme] 2htdp/image questions

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Wed Apr 21 13:32:34 EDT 2010

On Apr 21, 2010, at 11:14 AM, <engineer at alum.mit.edu> wrote:

> I've been trying to do something related to this discussion.  I'd like to
> convert a complicated 2htdp/image into a bitmap and back, hoping it will
> make for a quicker render.
> I have an animation with many shapes being drawn, however most shapes do not
> frequently change.  It seems clear to me (after some investigating) that my
> background being made of hundreds/thousands of shapes is my main problem, as
> opposed to the other calculations I'm doing.  I was surprised to find that
> even a non-mutating, constant image background was slow to render if
> initially made of many shapes.  Yet a single, large, cut-n-pasted image was
> not slow.

Another argument for caching bitmap representations of images.  But if I understand it right, Paul's application would call for caching something part-way down the tree, rather than just at the top.  If we were to cache bitmaps at every level of a tree, it would REALLY hog memory.

> How can I "flatten" the image?  I'm thinking that a bitmap with the shape
> info forgotten would really speed things up.  My plan is to separate the
> overall image-scene into a static background which updates only infrequently
> and a dynamic state which updates after every event.
> Sorry I haven't seen any obvious way of doing this myself after searching
> through the bitmap references, but I'm hoping for something like:
> (bitmap->image (image->bitmap fancy-scene))

As far as I know, the closest thing to image->bitmap is named render-image, but it's Subject To Change and uses all sorts of internal stuff.

At present, according to .../collects/mrlib/image-core.ss, an image has several parts, of which the most interesting is a "shape".  A "shape" is either
	(make-overlay shape shape)
	(make-translate dx dy shape)
	(make-scale xscale yscale shape)
	(make-crop points shape)
	or atomic-shape (which has a couple of variants itself)

What I'd like to do is add another option:
	(make-cached-shape shape)
and a publicly-available function that takes an image and wraps it up with a cache.  Using this function shouldn't change the externally visible behavior of anything, but may make some things more efficient.  In Paul's application, one might write

(define background (cache-image (build-the-complicated-background)))
(place-image foreground x y background)
; some time later
(place-image different-foreground different-x different-y background)

If anything DOES change in the background, either background will be rebuilt from scratch and reassigned, or it'll be mutated, and anything that tries to mutate a cached-shape will clear the cache.

Note that inside build-the-complicated-background, there could be other calls to cache-image, for PARTS of the background that are likely to stay unchanged for a long time.  The more of this you do, the more memory you are trading for time.

I was originally hoping to do this using class overriding, so I wouldn't need to change any of the existing image code or wait for a PLT release, but "shape", "overlay", etc. aren't implemented as classes, so that's not going to work.

Stephen Bloch
sbloch at adelphi.edu

Posted on the users mailing list.