Scaling text members with imaging
October 9, 2000
by Pat McClellan
Dear Multimedia Handyman,
I'm making a chart that I want to print all in one text cast member (around 8" x 10"). Well, I want to display that chart in my movie, except my movie is much smaller. Is there a way I can take a picture of the cast member and resize the sprite? Any other suggestions would be appreciated.
Pat M
Dear Pat,
As I understand it, you have a Text member that is bigger than the Stage. You want to keep it that size for printing purposes, but you need to display it on the Stage in a shrunken version. You know or have discovered that scaling the sprite or changing the dimensions of the Text member will not achieve your goal. Changing the dimensions of the sprite or member does not scale the font or other formatting. Let's look at the other options.
Text cast members (and other types as well) have a property called image. Basically, the image of a member holds a graphic picture of what that member looks like. You'll need to grab the image of your chart (Text member) and figure out the best way to scale it down and display it. There are two possible choices: you can copy the image of the Text member directly into the image of a Bitmap member and then scale that bitmap sprite down to fit on the Stage; or, you can copy the image from the Text member and scale it down before you paste it into the Bitmap member, and then display it without scaling that sprite.
Basically, the choice is whether to do the scaling during the copyPixel() function, or later to the sprite. I did some experiments to compare the resulting image quality and I can't see any difference at all. Neither operation is particularly quick when dealing with a Text member that has a lot of formatting -- averaging around 100 ticks on my 500 MHz G3 -- but there's no significant speed difference between the two options. Here's a look at the code you could use:
on directCopy sourceMem, targetMem, targetSprite, scaleFactor
sourceImage = member(sourceMem).image
sourceRect = sourceImage.rect
destRect = sourceImage.rect
imageWidth = sourceImage.width
imageHeight = sourceImage.height
newImage = image(imageWidth,imageHeight,32,0)
(newImage).copyPixels(sourceImage, destRect, sourceRect)
member(targetMem).image = newImage
member(targetMem).regPoint = point(0,0)
sprite(targetSprite).width = imageWidth * scaleFactor
sprite(targetSprite).height = imageHeight * scaleFactor
end
on scaleCopy sourceMem, targetMem, targetSprite, scaleFactor
sourceImage = member(sourceMem).image
sourceRect = sourceImage.rect
destRect = sourceImage.rect * scaleFactor
imageWidth = sourceImage.width * scaleFactor
imageHeight = sourceImage.height * scaleFactor
newImage = image(imageWidth,imageHeight,32,0)
(newImage).copyPixels(sourceImage, destRect, sourceRect)
member(targetMem).image = newImage
member(targetMem).regPoint = point(0,0)
sprite(targetSprite).width = imageWidth
sprite(targetSprite).height = imageHeight
end
In the directCopy method, the source and destination specifications are identical, so there's a more direct method of doing this operation. You can directly set the image of the targetMem equal to the image of the sourceMem. This approach takes a shortcut around the Imaging Lingo and makes the operation twice as fast to execute (mileage may vary).
on moreDirectCopy sourceMem, targetMem, targetSprite, scaleFactor
sourceImage = member(sourceMem).image
imageWidth = sourceImage.width
imageHeight = sourceImage.height
-- here's the shortcut
member(targetMem).image = member(sourceMem).image
member(targetMem).regPoint = point(0,0)
sprite(targetSprite).width = imageWidth * scaleFactor
sprite(targetSprite).height = imageHeight * scaleFactor
end
This method is faster and equal in graphic quality to the other methods, so I'd go with this approach. However, there's one interesting difference to note: the alphaDepth. AlphaDepth is an optional parameter of the image() function. Take a look up there in the scaleCopy or directCopy methods on the line where the newImage object is created.
newImage = image(imageWidth, imageHeight, 32, 0)
That last parameter, 0, is the alphaDepth. I can't find any documentation on alphaDepth or how to use it except for the following sentence in the Lingo dictionary in a section about the image() function. It says:
The alphaDepth, if given, is used only for 32-bit images and must be 0 or 8.
That's all they say! My tests showed that if you specify 8, the resulting bitmap image retains alpha channel info and therefore has a transparent background, even if the bitmap sprite's ink is set to Copy. The moreDirectCopy method above seems to default to an alphaDepth of 8, so you'll always get this transparency. Going back to the copyPixel() alternative: if you use 0 for the alphaDepth, the background is white, even if the background of your text member is a different color. Interesting.
When I created my Text member, I used the html property to paste in a chart that has different colored backgrounds for the table cells. (Note that there's no way to actually enter this kind of formatting into a Text member other than using Lingo to set the html of the Text member.) When this Text member is displayed on the Stage, the table cells are colored correctly. However, the cells' background colors don't copy correctly in any of the operations in this article. I'm not sure whether it's a bug with the imaging or with the html rendering.
There's not much to show for the demo, but if you'd like to look through my test file, you can download it. Use the message window to call the functions we discussed in this article.
Director 8 download for Mac or Windows.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.