Director: Better, faster great-looking image resampling
A few months ago I was posted about how Director’s scaling code looks great when shrinking something more than 50%, but for shrinking stuff less than 50%, the image gets jaggy.
My solution at the time was to use some bilinear resampling code written for Lingo, which I modified from an existing function written by Josh Chunick. It worked like a charm, but it was pretty slow. Good for an occasional resample, but too slow to use in, say, a game.
Well, when doing some graphics experiments for a new game, I decided to see what happened if I first doubled the source image before shrinking it down to a size less than 50% of the original. I originally didn’t try this because I figured that the double-sized pixels would add jagginess into the final image, negating the benefit of Copypixel’s greater-than-50% scale.
But I was wrong.
The resulting image looks great even when scaling small amounts. It’s a little slower than a single copypixels operation, but still incredibly quick and much faster than the bilinear scaling code. So I’ve written a new image resampler that uses a single copypixels operation if the scaling is more than 50%, and uses the double-before-shrinking technique if the scaling is less than 50%. The new code is posted below. Check out my previous blog entries to see examples of how Director fails with smaller scales, and how Bilinear fails with larger scales.
I should add a new tag on my blog for “Duh”.
on resampleImage theImage, newWidth, newHeight
-- 2006 Hanford Lemoore; feel free to use, redistribute, and modify.
-- this resamples an image to a new size (smaller) using copypixels so that the image
-- looks smooth. only use this to shrink images.
-- This uses a double-before-shrinking procedure when scaling less than 50% to get a better
-- image than copypixels alone. for more information see the site:
-- http://blog.hanfordlemoore.com/2006/07/12/director-better-faster-great-looking-image-resampling
newimage = image(newWidth, newHeight, 32)
if newimage.rect = theimage.rect then
-- return the original image
return theimage
else if (newimage.width < (theimage.width/2)) and (newimage.height < (theimage.height/2)) then
-- use copypixels like normal
newimage.copypixels(theimage,newimage.rect,theimage.rect)
return newimage
else
-- first upsample, then downsample
tempImage = image(theImage.width * 2, theImage.height * 2, 32)
tempImage.copypixels(theimage, tempimage.rect, theimage.rect)
newimage.copypixels(tempimage, newimage.rect, tempimage.rect)
return newimage
end if
end


I'm Hanford Lemoore. My parking skills are unparalleled.





