Photo Histograms Everywhere!
Most of you probably know that I am a huge fan of photography, my Flickr account being the prove of it. But besides uploading my own photographs I also love to give other photographers feedback on their photography.
One of my common things I like to do when judging a photo is to have a look at the photo’s histogram. Unfortunately to do so, you need to download the photo, load it into your favorite photo application and then look at the graph. This gets a bit tedious if you want to do it quite often.
So I decided to make my own solution that will work in any browser. I have some experience with bookmarklets, and as they are highly cross-browser they looked like the way to go. Unfortunately most browser do not support the next generation CSS/Javascript that will allow for the histogram data to be read out in the browser only, so I had to extend the concept with some server side code. It all worked out though, and after less than a day coding I now have a working system.
Server Side Code
The server side part is a PHP script that parses the photo’s pixels and generates a nice graph using the Google Chart API. The service returns a javascript function when run in the bookmarklet but it can also be called as a service to generate a image or a html block. Here is an example of an image and it’s equivalent histogram created via the server side script.
The url of the photo is
http://farm4.static.flickr.com/3122/2806124294_08cc5efc74.jpg
And the url of the corresponding histogram is
http://histogram.cristianobetta.com/?type=image&rgb=true&image=
http://farm4.static.flickr.com/3122/2806124294_08cc5efc74.jpg
As you can see, the histogram script takes 4 parameters. The image parameter defines the image to be parsed. This can be either a jpg, png, or gif file. The rgb parameter let’s you choose between a grayscale or rgb histogram. A grayscale histogram for this image would look like this.

Finally the type parameter let’s you choose between an image (like the examples above), html object (image pre-wrapped in a img html object) or a piece of Javascript (js, callable as getSrc()).
Since September 3rd 2008 the service also take a width parameter. For more info see the end of this post.
The Bookmarklet
The web service gets more powerful when we add a nice bookmarklet. I wanted to be able to load the histogram for any image on the web with just a few clicks. So, I decided to make a bookmarklet that loads a simple GUI, prompts you to click the image you want to analyze, and then shows you the histogram. The result was a bit more code than I hoped for but more solid than I expected. I think the easiest way to show you how it works is with a video.
Download
So enough talking, I guess you want to try it yourself. Drag this bookmarklet into your bookmarks bar and try it out.
If you really like the service, I would appreciate if you would install your own version of the server side script on your own server, simply because it will save me bandwidth feel free to use the webservice and bookmarklet as much as you want. You can also decide to download the webservice to your own host if you want to. When installed on your own server, change the host variable in the bookmarklet to point to your own server and all should be fine.
The source of both the server side script and the bookmarklet are available to anyone who wants to play with them and released under GPL2.
Improvements
There are still a few things that need to be worked out. I invite anyone to have a look at the code and help me out. Some of the main improvements currently are:
Caching – Currently nothing is cached. A little bit of caching would make things way less bandwidth demanding.This has been implemented since September 3rd, 2008. Javascript, image, and HTML output is now by default cached for 24 hours.Custom size – Currently the server side script returns a fixed size image, but it would be arbitrary to allow the bookmarklet to send the parameters defining the size.I added a simple height parameter that is optional. Images will always have a aspect ratio of 2:1 as this makes histograms look better, plus it makes it easier to oblige to Google Chart API’s demand of staying under 300.000 pixels. Therefore the max height you can specify is 385 pixels (making the image 385×770, or 296.450 pixels).- Correct Histogram Calculation – I don’t think that I’m far off at the moment, but I might have scaled some of the histograms just slightly off from what it is supposed to look like. I need to read up on how histograms are generated in pro-tools.



nice app! I “installed” it on my firefox
Very well done Cristiano,
not only the bookmarklet works VERY well, but it is also extremely useful!
THANKS!!!
Hi Cristiano – nice work. I’ll give it a try out.
I found this from your posting in the Utata Group Discussions. Very cool tool!
I don’t know if I will actually use it any time soon, but I am definitely bookmarking this to remember it for the future
Now, how about some tips on what to look for in those histograms?
@everyone thanks for the support. glad it can be of use to some people.
@sheila I think that that is an entire blog post on its own. but maybe I will do that one day. OR, maybe I can give some photography tips and tricks on Barcamp (not that you are going).
Hi
I just peeked into the bookmarklet.js code and notice that you wrote your own URLEncode function with the comment:
// apparently JS does not have a urlencode of its own.
But there is
See encodeURIComponent here
Great work
Simon
@simon ahh, admittedly, I took quite some code from bookmarklet examples, and this comment is actually not from me but copied. If I have time I will rewrite the code (or maybe you can) to work with the build in encodeURIcomponent.
Hi,
I’ve seen your Histogram function (bookmarklet) and I would love to use it!. The only problem I found was the fact that your script can’t handle spaces in the image string. Is it possible to change this?
Many thanks and good work!
Doesn’t it? How interesting. Do you have an example of a site that has images with spaces? I will try and fix it then.
I see my code is deleted from the comment, so you’ll have to use the link. To be sure I did everything alright I’ve made another page (see the link on this comment) which has no spaces and that works fine.
Sorry for the split post!
With spaces: http://miroen.nl/public/histogram_test.html
Without spaces: http://miroen.nl/public/histogram_test2.html
@Jeroen: Yeah I already removed your first post. Can you explain what this test page is supposed to show?
EDIT: Ahh, I see the issue. Yeah. We probably would need to urlencode the entire url, and decode it server side. I will do this as soon as I got some time (say tonight).
Also: anyone interested in a Firefox Extension for this?
Hi Cristiano,
Any luck with the “spaces” problem? I’ve downloaded your code, but I’m an ASP guy, so the PHP part is like abracadabra to me. Couldn’t figure it out by myself.
I’m a lazy bastard so I haven’t looked at it yet
. Remind me again tonight, ok? It should be a fairly easy fix.
Cristiano,
here’s your “wake-up call”! Please take a look at the spacing problem. Thanks,
Jeroen
Haha, you’re forgetting the 1 hour difference with the UK I think. I’m still at work. Will look at it though tonight.
Ok Jeroen, so I had a look, and guess what: I don’t need to change anything! My Javascript bookmarklet uses the encodeURIComponent function to encode an image string with spaces to replace the spaces by %20. The server side code can then use this encoded url without problem.
In your examples you have forgotten to encode the strings. I don’t know how this happens, I take it you’re building your own system. If you are using PHP, make sure to use urlencode to encode the url. If you are using JS, make sure to use encodeURIComponent.
Can I ask what you’re trying to build?