[squeak-dev] Who understand bilinear interpolation for reducing image size?

Bert Freudenberg bert at freudenbergs.de
Tue Dec 9 09:59:48 UTC 2014


> On 09.12.2014, at 00:45, tim Rowledge <tim at rowledge.org> wrote:
> 
> 
> On 08-12-2014, at 3:01 PM, Bert Freudenberg <bert at freudenbergs.de> wrote:
> 
>> On 08.12.2014, at 21:15, tim Rowledge <tim at rowledge.org> wrote:
>>> 
>>> The ScratchPlugin implements a prim to shrink a 32bpp image by use of bilinear interpolation. Unfortunately it completely ignores the alpha channel in 32bpp pixels and does some rather odd futzing to kinda-sorta fake handling of transparency.
>>> 
>>> I can see how to add in (what I think would be) proper ARGB interpolating, and I think that simply removing the futzing would be correct - but I’d much rather have some input from somebody with a bit of image processing theory so there is some hope of my final result being actually correct.
>> 
>> Why would you like to change it? To accept a wider range of inputs?
> 
> Well, the main need is to stop it breaking imported images. A frequent problem I’ve had reported is that importing gifs & pngs results in images that simply aren’t correct. Transparent backgrounds that are white, or black, for example. A fairly common problem is ‘transparent’ source pixels that are in the file as 0 alpha but RGB = white.
> 
> In the process if trying to sort them out it was noticed that this scaling prim strips away any alpha channel; I don’t particularly mean partial transparency, just all of it. Feed in a pixel that is A=255 and it comes out A=0. Bit of a pain if you ever need to display it with Form blend.

Looking at the code it should preserve pixel value 16r00000000, which is the only one recognized as transparent by BitBlt.

It's the job if the image importer to make sure that if alpha is zero, the whole pixel value must be zero.

>> This purposely does only output fully opaque and fully transparent pixels, which likely is a requirement further down the pipeline. Makes rendering faster, too: true alpha-blending is expensive.
> 
> The code gives the impression of having been written before the 32bpp ARGB pixel format was put into use.

Nope. The ARGB pixel format has been around forever. Dan took Smalltalk-80's 1-bit BitBlt and extended it to work in 1-2-4-8-16-32 bits per pixel before the first Squeak release.

> That could explain why it doesn’t set the alpha bits for the output.

No. What *has* changed is that people are much more willing to waste *thirtytwo* bits for *each* tiny pixel in stored image files nowadays. Think about it. Eight bits for transparency where surely one would suffice, right? I'm just half kidding. This code is from an era where "transparent image" meant "GIF". Which didn't even have 1 bit of transparency per pixel, but I think 1/32nd of a bit, if my math is correct (8 bits per pixel with 1 out of 256 values meaning "transparent").

There simply was no way to import an image with 256 levels of transparency, so the code did not waste cycles dealing with them. 32-bit PNGs got popular much later.

The most common way to get a transparent sprite in Scratch is actually importing a photo (directly from camera, or via JPG, no transparency in any case) and use the eraser tool in the image editor to erase pixels. Again, no smooth alpha there.

> I could of course just do a bitblt with the fixAlpha rule but it’s faster to fix it inside the prim if possible.

Agreed.

> The question becomes one of the final effect that is wanted - doing ‘the right thing’ by mixing the alpha values is simple and works ok for the examples I have right now but yes, they’re not using partial transparency and are finally displayed with Form paint instead of blend. And that is an issue too, since people are quite likely to try importing images with partial transparency from assorted paint programs and clipart, only to find it looks really strange.

Yep. Kids these days ...

> The old code was fudging transparency and effectively rounding it up to opaque if the weighted average was > ~half.  I could do similar easily enough I think.
> 
> But I’m not at all knowledgeable about image processing stuff, which is why I ask.

Well, I would preserve the output (only 0 and 255 for alpha) but extend the inputs: instead of comparing input pixel value to 0 to determine if it's transparent, compare the alpha. I think if the pixel value is a sqInt then comparing "pix < 0" would work, although doing an unsigned compare with 16r7F000000 would be less obfuscated.

- Bert -

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4142 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20141209/c0cf19de/smime.bin


More information about the Squeak-dev mailing list