[Techie] Colour matching pngs
Sep. 27th, 2007 12:22 pmI felt like posting something techie about things we were looking at at work yesterday. I know this is what people do in grown up blogs but I thought there are enough technical people on my friends list that it wouldn't be an entirely wasted effort. So that's just a warning that some may want to skip.
A common problem that is had on the web is that pngs are very clever. They are clever enough to have embedded colour profile information that viewers can use to determine how to display things. Unfortunately the software is often less clever and makes assumptions or does other stupid things. The upshot of it is that if you have a png that you put a colour into it may not be the same colour when viewed everywhere.
In practice we came across this problem that we have a coloured background (done by the html) which was olive (colour code: #808000). We then had a png that should have stuck onto the side of this which was the same colour so would look like the same chunk. Unfortunately it was displayed as a slightly darker colour (#757500). This was only in IE, fireforx was fine.
Now I've played around with the png file format before (when making palette based variable-transparency pngs) [0] and its actually a nice format. It is just chunks of data that are easily and mostly independantly manipulable.
There are a few required chuks (the header, and the data and the end chunk and in certain formats a palette) and then optional chunks. Optional chunks don't need to be supported but provide enchancements if they are. The colour stuff is all in there (in separate sections of RGB description, gama and colour profiling). We played around with trying to change the sRGB section to show the correct values but it is possible that IE wasn't understanding it since it seemed to use the gAMA section (if I remember its id code correctly) anyway.
In the end the solution that was incredibly simple. Changing chunks involves having to recalculate checksums to make sure the data is valid. These CRCs are at the end of each chunk and mean that any change to a chunk involves recalculating the checksum.
In the end the code we implemented just removed any optional sections we didn't want in their entirety. The whole chunk went so no checksum calculations needed. This worked a charm. With no colour information to use IE (and everything else) just used the colours as given.
The added bonus is the file sizes are smaller too. :)
Edit: Do feel free to comment if you found this post interesting enough to want me to consider doing more if I ever come across things I think are interesting. No idea how often that will be though.
[0] The original playing about was because of transparency issues in IE. It was a few months ago so details are more sketchy but roughly IE doesn't like more than 1 bit transparency in pngs (ie the ARGB type thing). They do however support palette based transparency where each pixel is given a paletter entry, a palette defines the colour and a new chunk defines the transparency of each of those indexes. Strangely this works better. So I had to hand write an appropriate image (just the transparency chunk) because I could find no software that supported this image format in editing and saving. I can remind myself of full details if anybody is really interested. Suffice to say though that was something that was done one off and not automated for lots of complex reasons. In theory some kind of conversion should be easily possible though in theory...
A common problem that is had on the web is that pngs are very clever. They are clever enough to have embedded colour profile information that viewers can use to determine how to display things. Unfortunately the software is often less clever and makes assumptions or does other stupid things. The upshot of it is that if you have a png that you put a colour into it may not be the same colour when viewed everywhere.
In practice we came across this problem that we have a coloured background (done by the html) which was olive (colour code: #808000). We then had a png that should have stuck onto the side of this which was the same colour so would look like the same chunk. Unfortunately it was displayed as a slightly darker colour (#757500). This was only in IE, fireforx was fine.
Now I've played around with the png file format before (when making palette based variable-transparency pngs) [0] and its actually a nice format. It is just chunks of data that are easily and mostly independantly manipulable.
There are a few required chuks (the header, and the data and the end chunk and in certain formats a palette) and then optional chunks. Optional chunks don't need to be supported but provide enchancements if they are. The colour stuff is all in there (in separate sections of RGB description, gama and colour profiling). We played around with trying to change the sRGB section to show the correct values but it is possible that IE wasn't understanding it since it seemed to use the gAMA section (if I remember its id code correctly) anyway.
In the end the solution that was incredibly simple. Changing chunks involves having to recalculate checksums to make sure the data is valid. These CRCs are at the end of each chunk and mean that any change to a chunk involves recalculating the checksum.
In the end the code we implemented just removed any optional sections we didn't want in their entirety. The whole chunk went so no checksum calculations needed. This worked a charm. With no colour information to use IE (and everything else) just used the colours as given.
The added bonus is the file sizes are smaller too. :)
Edit: Do feel free to comment if you found this post interesting enough to want me to consider doing more if I ever come across things I think are interesting. No idea how often that will be though.
[0] The original playing about was because of transparency issues in IE. It was a few months ago so details are more sketchy but roughly IE doesn't like more than 1 bit transparency in pngs (ie the ARGB type thing). They do however support palette based transparency where each pixel is given a paletter entry, a palette defines the colour and a new chunk defines the transparency of each of those indexes. Strangely this works better. So I had to hand write an appropriate image (just the transparency chunk) because I could find no software that supported this image format in editing and saving. I can remind myself of full details if anybody is really interested. Suffice to say though that was something that was done one off and not automated for lots of complex reasons. In theory some kind of conversion should be easily possible though in theory...
(no subject)
Date: 2007-09-27 11:58 am (UTC)I use Paint2, an application developed in 1995 by staffers at Electronic Arts for doing palettes on Playstation games ;-)
(no subject)
Date: 2007-09-27 01:07 pm (UTC)(no subject)
Date: 2007-09-27 01:17 pm (UTC)And yeah, back when I was developing stuff for mobile phones I had incredible amounts of trouble with PNG for pretty much this reason (mobile screens are radically different in profile from CRT monitors).
I eventually came to the conclusion that it was a design flaw in the PNG spec not to have a "do not adjust for monitor settings" bit somewhere in the image descriptor which you can set for special cases. Because that's the only way you're ever going to colour match a PNG to something else, which is something you sometimes validly want to do.
(no subject)
Date: 2007-09-27 01:25 pm (UTC)The spec says that colour information shouldn't be put in unless it is known or you can make a pretty good guess. Unfortunately from what I found many things decide to base this colour information based on OS. Which is just crazy. I think the correct thing for them to do is if they can't make a good guess don't make a guess at all and let the decoder worry about it without hints. That is effectively what we forced in the above scenario and it works a charm.
So yeah, I think there is something in the spec, the flaw seems to be that it is entirely optional whether to include it or support it. :( Its a shame that the sRGB can't be made compulsory if you support other colour things.
As you say though, colour matching is such an obvious thing to want to do that its surprising it isn't better supported. It seems though that a lot of the sites talking about it are thinking about photos and I suspect it was a lack of foresight that you might want it for simpler things where actual colour is more important than the overall "niceness" of the picture.
(no subject)
Date: 2007-09-27 01:26 pm (UTC)(no subject)
Date: 2007-09-27 01:30 pm (UTC)Techy stuff is interesting, even if I'm highly unlikely to find it relvant to anything.
(no subject)
Date: 2007-09-27 01:33 pm (UTC)Heh. Typical. Still, at least that beats supported-but-broken (hello CSS!).
(On one occasion I did ask if we could fix one optional feature and was told: No, fixing it would break too many things!)
(no subject)
Date: 2007-09-27 02:01 pm (UTC)http://www.yourfilelink.com/get.php?fid=393847
(no subject)
Date: 2007-09-27 02:24 pm (UTC)(no subject)
Date: 2007-09-27 02:31 pm (UTC)(no subject)
Date: 2007-09-27 02:41 pm (UTC)(no subject)
Date: 2007-09-27 02:42 pm (UTC)(no subject)
Date: 2007-09-28 09:41 am (UTC)Colour profiles in PNGs are one reason. I've always gone for the solution of having it so the PNG has a valid alpha channel, then a colour channel matching the background (alot of programs assume if it's transparent you want to save the alpha areas as black in the RGB area). This means in alpha supporting browsers it's shiny, in IE it copes okay (however you would still have the problem above).
But yeah I've seen this with Gifs and jpegs too, I blame that on colour profiles of the system being implimented differently. (e.g. applied to images but not to the background).
As for random profiles, photoshop seems to believe everything should be in it's colour profile, which is annoying when Mac's have really good colour profile support built in (and I generally leave alone as I don't do anything that clever). I would assume Vista has reasonable colour profiles these days too.