Interpretation of "background colour index" in GIF specification - gif

If you look in the GIF specification and search for "Background Color Index", you see the following description:
vii) Background Color Index - Index into the Global Color Table for
the Background Color. The Background Color is the color used for those
pixels on the screen that are not covered by an image. If the Global
Color Table Flag is set to (zero), this field should be zero and
should be ignored.
There is an ambiguity here, which is that if the "Global Color Table Flag" is set to zero and this field is ignored, then it is undefined what background colour of a GIF actually should be if the image data itself does not cover the entire image area. This possible because every image data block specifies left/right/width/height independently and there is no requirement that every pixel must be encoded by the image data.
Am I misinterpreting this? If not, then in the presence of this ambiguity, what is the de facto behaviour of GIF implementations today?

The background color index is often ignored by decoders (including some modern browsers), whereas GDI+ (eg. Windows Paint or .NET WinForms controls) respect it. GDI+ handles it like this:
If there is no global palette, OR the first frame has transparency (the Transparent Color Flag is set in the Graphic Control Extension), then the background is transparent
If there is a global palette AND the first frame has no transparency (there is no Graphic Control Extension for the first frame, or the Transparent Color Flag is not set for it), then it means a color index from the global palette and is significant only if not the whole virtual screen area is covered by the first image, or when the "Restore to background color" disposal method is set for a frame. In latter case it does not matter if a possibly existing local palette does not contain the background color.
To demonstrate its effect I created a simple animation of two frames with my encoder, and then played with some settings (feel free to download the images and see their content in a file viewer because I added some textual hint in the files). You can use this app to see the animations in a Win32 app using GDI+ rendering.
Common properties:
All images have a global palette so the the background color can be set.
The background color is set to green.
The Virtual Screen Size is 64x64 pixels
The first frame is 48x48 pixels
The second frame is 32x32 pixels
The animation rendered by your browser
The 2nd frame by GDI+
Description
None of the frames are transparent, there is no clear.
Both frames are transparent, there is no clear.
Only the 2nd frame is transparent, there is a clear after the first frame.

For the example, Safari uses black as the background. With Win10 photo viewer it's hard to tell, as it uses a black background anyway. Chrome, IE and Edge use white.
The spec doesn't define the behaviour when there's no background colour and you need one, so I guess arbitrary choices is what you'll get, though I vote for transparent being the most sensible.

Yes, the ambiguity is indeed present. Background color is largely a derelict of GIF87a, currently only necessary for 'Restore Background' frame blending mode.
By now, all decoders I have seen treat pixels not belonging to any frame as transparent even if transparency flags in all of the frames are zeroed.
Consider this GIF, for example:
See how your browser interprets it? The whole background is transparent.
P.S.: in case it does not loop, reload the page using Ctrl+F5.

Related

Determing the color of uncovered GIF pixels

Here is a GIF containing just one image, 75 pixels wide.
The image has an Image Descriptor with an Image Left Position of 25.
So the leftmost 25 pixels of the image are not covered. Since the GIF specification states that
The Background Color is the color used for those pixels on the screen that are not covered by an image.
and the Background Color Index is 0, and the first entry in the palette is (0, 255, 0), I would think those leftmost 25 pixels should be green.
Instead, the browser renders those pixels as transparent.
Can anyone tell me why this is? Have I missed something in the specification?
I've managed to find https://legacy.imagemagick.org/Usage/anim_basics/#dispose. In discussing why ImageMagick uses transparency for disposal method 2, it states (emphasis mine)
There is some thinking that rather than clearing the overlaid area to the transparent color, this disposal should clear it to the 'background' color meta-data setting stored in the GIF animation. In fact the old "Netscape" browser (version 2 and 3), did exactly that. But then it also failed to implement the 'Previous' dispose method correctly.
On the other hand the initial canvas should also be set from the formats 'background' color too, and that is also not done. However all modern web browsers clear just the area that was last overlaid to transparency, as such this is now accepted practice, and what IM now follows.

Custom icon color in ApplicationBar for Windows Phone 8

I have used the ApplicationBar's Background and Foreground colors respectively, and can see that it changes appearance accordingly. So if I want my icons to turn up green, I just set the Foreground property. So far so good.
My question is how do I change just one icon, not all? Assuming I want them all standard black/white (depending on the light/dark theme setting), but one should be green. I tried playing with the png file that represents the icon, changing that to green (the colored parts of it, most of it is transparent of course), but it still shows up as white. Can it be done with an Opacity Mask? Or is there another way?
You can't change the color of a single App Bar icon like this.
Effectively the SDK only reads the transparency (alpha) channel of your icon PNG and converts that to black or white with the required transparency.
If your phone is in light theme it will use black pixels, in dark theme white pixels.

Make JPG white background transparent

I am loading some images and I want to go from PNG to JPG to have a smaller file size. However as JPG there is no transparency information so the background of the image shows up as white.
How can I make this white background be transparent once I load my images?
Thanks in advance
I am assuming that you want to change the white pixels to transparent pixels at runtime. First I'll just say that the BEST answer , is to just use the PNG format. My opinion is that doing something like this at runtime is not a good solution. If you have that many images that the file size matters, then the runtime processing brings along it's own negative of a long pause while processing the images.
I personally would explore what I could do to decrease the size of the PNG files, and would likely NEVER use a solution like this.
However, if you choose to go this route, what you need to do is this :
Convert the image to a BitmapData with an alpha channel.
Loop through the BitmapData and make those pixels transparent.
or
Use the threshold() method of BitmapData.
As someone mentioned in the comments for your question, using white as the background color is not a good idea as ALL white pixels will be made transparent, not just the background ones.
So choosing a color that is not in the palette of any of these images is what you want to use as a background color
As a commenter noted, the threshold() method of BitmapData would probably work best.
JPG (Technically, JPEG File Interchange Format) files, as understood by common browsers and graphics applications, do not support storing an alpha channel with the image like PNG does. Depending on your application, you might want to store a separate black-and-white "image" file which is the transparency mask for the JPG, and use the pair. There are extensions to the format that can be used in custom software, but they won't be understood elsewhere.
But first, make sure that JPG is really what you want to use. JPG is only appropriate for "photographic" images, which don't typically have transparency masks (though there are certainly exceptions). If the image is more Icon/Drawing-like, then it is likely that JPG won't be much smaller than the PNG anyway, and have ugly aliasing artifacts, so just optimizing the PNG will give you better results.
You may want to consider embedding the png's in a Flash library, then export as swf. You can then use Flash to compress your png using the lossy JPEG algorithm, but it will still keep the alpha channel. This could result in much smaller file sizes but with the benefit of keeping the 8-bit alpha channel (each pixel has 256 transparency levels).
By masking out a specific color, you'll only get a 1-bit alpha mask (a pixel is either fully visible or completely hidden.) You can also run into problems like when the color in the image corresponds with the matte color, which deletes pixels from the actual image you want to display.
The other problem with using a matte color in a JPEG image is that the JPEG compression will leave artifacts, especially around the edges of the object and the matte color. This makes it hard to properly mask out a specific color.

beginner questions about canvas elements with imported images... caching and changing colors

Couple noob questions about the canvas element in html. First, are images that are imported into a canvas element cached? Across browsers?
And second can I import a black and white png into a canvas element and then change the black color to a different color?
There is nothing in the canvas spec saying that images must be cached.
With a canvas, you need an Image HTML element already. The only way it can interact with a canvas is to call .drawImage() on the canvas' context.
There's no caching or saving after that event. The canvas prints the pixels of the image onto itself and then forgets that anything ever happened. No history, no caching.
You can easily draw (no importing) a black-and-transparent png onto a canvas, and then easily change the black color to a different color.
You would change the canvas context's globalCompositeOperation to be 'source-atop' and then fill the image space with the color of your choice.
You could do the same if it was black-and-white instead of black-and-transparent, but it would take more work.

Is there a free tool for rendering a webpage to a PNG with a transparent background?

Say I have a very simple html page, containing a single line of text. I'm looking for a tool that would take that line of text, and superimpose it on a transparent PNG background. That logic would be applied to ALL elements on the page: if no background is specified, and the background of parent elements doesn't leak through, then a background should render as transparent.
As in transparent-pixel-in-image tranparent.
Is there a tool for this?
There are various command line tools for this sort of thing, most of which depend on WebKit somehow, eg. webkit2png, the hard part is going to be making the background transparent. Every screenshot tool I've ever tried sets the background opaque, even if the CSS background colour is transparent. The best approach might be to set the background to some unusual colour by default and then use a tool like ImageMagick to set that particular colour transparent.