As I mentioned in the previous post, I’m currently working through a re-write of the various tutorials I had done about using Wavelet Decompose for skin retouching.
I’m about 2⁄3 of the way through it now and expect to have it finished shortly.
I also previously mentioned that I’ve been reaching out to a few folks to see if they might be interested in writing some articles for the site.
I’m extremely pleased to say that Ian Hex is stepping up to the plate with a neat tutorial about darktable that is being written right at this very moment!
If you haven’t had a chance to see Ian’s work I highly recommend stopping by his site at http://lightsweep.co.uk/ to get a gander at some epic images from the UK.
I desperately want to hop on a plane and visit after seeing them!
His self-professed mission is:
..to show off the beauty of British landscapes and architecture to the world
and I’d say he’s doing a bang-up job of it so far!
I’m working my way through some of the suggestions I’ve received from many folks.
In particular, the “px” icon in the upper left to slide open the navigation and Table of Contents has been changed to a (hopefully) more familiar ‘hamburger’ icon.
I’ll also be testing some other things in the coming weeks as time permits such as having a TOC show up by default in the right ⅓ of the page at the top.
Don’t expect it too soon as I want to focus on writing more content first.
I’m aiming for a December-ish timeframe for a more official launch and want to make sure there is a decent amount of material for folks to consume.
Speaking of material, I’m starting work on a tutorial for skin retouching with wavelet decompose.
I’ve written about this many times before, but want to port the ideas over here.
“Dot Eyes Closed” wavelet decomposition
I have a few extra thoughts surrounding the use of wavelets as well as some minor changes in my workflow with them that should make a new writeup more interesting (hopefully).
I’ll also focus specifically on skin retouching as opposed to some of the other things that can be done with wavelets.
I have reached out to some of my favorite amazing photographers using F/OSS in their workflows and the response has been overwhelmingly positive. I’ll speak more about the folks in a later post, but I am personally very thankful that they have taken the time to respond and that it’s been so positive!
I’ve pretty much finished up the first article mentioned in the previous post.
There is still a long way to go.
As much as I’d like to believe that “If you build it, they will come”, the reality is that nobody is coming until there is something worth coming for.
So I’m working hard on getting good content in place.
I’m also acutely aware that nobody will stay unless good content continues to be published, but that’s for another post.
I am thinking the next article that I’ll update/port will be either Luminosity Masks or Skin Retouching.
I am also thinking that a port of my older color curves tutorials might be nice as well (particularly using sample points).
That should get me to four good tutorials to start the site with.
At that point I can start queueing up the next few asap.
I also wanted to do more than straight single tutorials, though, which brings me to a question.
These would be similar to the Digital B&W article I’ve already ported.
If you’ve read most of my tutorials on my blog, then you’re already familiar with what I’m thinking for these.
These are straight tutorials looking at a single (usually) effect and how to achieve it.
The primary focus is on the steps and tools to produce the desired result.
I am envisioning a workflow article to be more of a look at the creative process to achieve a final resulting image.
This is more along the lines of another previous set of posts I had written about: The Open Source Portrait and the Open Source Headshot.
These articles would focus on all of the steps and tools to arrive at a resulting image.
The difference from a tutorial article is that if a tutorial article might explore how to use Wavelet Decompose for skin retouching, a workflow article might include using that technique (among others) to realize a final vision.
Showcasing some of the amazing work I see occasionally is important as well, I think.
One, the artists doing this great work really do deserve to be talked about and exposed to a wider audience.
Second, great work by F/OSS using artists act as ambassadors for what is possible using these tools.
Too often the low opinion of many concerning F/OSS tools is framed by sub-standard work being shown.
There are some amazing photographers working with these tools, and my hope is that they can stand as examples to not only showcase F/OSS but also as a bar for others to aim for (and hopefully smash through).
I’m not 100% sure on this yet, but I think I was originally viewing this as a complete workflow from start to finish, including actually shooting.
This is more focused on the photographic process in general and things to keep in mind while capturing the shots for processing later.
I’m not at all sure about this, but the idea is there.
Possibly posts that are very short and targeted at a very specific task or function.
Something that might not really warrant a long-form article but could still be quickly useful for others.
I am reminded of this due to an old video of mine that I had done quickly for someone on G+ about how to add a watermark over an image.
You can tell why making videos is best left to folks like Rolf…
Thanks to darix (once again) over in irc on #darktable for setting up a Discourse instance for me to play with.
I have used it previously on boingboing.net, and I rather like what I’ve seen.
It also appears that there may be a way to embed thread posts as well, which would be a nice solution for commenting.
The first article is almost done being ported and formatted.
For anyone who’s curious, it’s a long post from the five part series I did on B&W conversion using GIMP (originally published on my blog).
The writing is going a bit slow because I am also feeling out the formatting and a couple of other minor visual things as they relate to a full-blown article.
Of course, it doesn’t help that it’s also a really, really long article…
For those of you bothering to read this blog, and who want to take a look at the state of that article, it can be found here:
Pixls.us: Digital B&W Conversion (GIMP).
Just don’t forget to let me know if anything looks funky, or with any suggestions/comments/criticisms.
Speaking of which, one of my first conundrums while working on it was a question of load times vs. convenience.
The original article was written as five separate blog posts which kept everything in reasonably bite-sized chunks to digest.
The problem is that as a reader I am sometimes annoyed at having to click through multiple pages to read an article and I thought that most readers here might feel the same way.
One of my concerns was load times and rendering speed of large pages.
I think I have all the assets set to load as quick as possible above the fold.
I’ve tried to optimize all images as much as possible and am making sure to define discrete width and height attributes in the html to help the browser render and not have to reflow (hopefully).
There are still a few optimizations that I have to implement that I haven’t yet (minify javascript and concatenating all my stylesheets for actual delivery), but I have them in the queue to do.
Oh, and spritesheets for some assets that I will get around to making soon as well.
So my current thought is to keep the articles to a single page, even if they are long.
I am also 100% open to other ideas as well so if you have one feel free to hit me up!
Long pages can be a bit cumbersome to navigate, though.
To help make it easier to target relevant information in the page, all of the headings in a page should have a unique id attribute.
This means that users will be able to link directly to sections of a long page (this seems to have fallen out of favor with many websites - why?!).
For instance, I can link directly to the previous section of this post by including the id of the element in the url:
I’m not 100% sure this is obvious, but the “px” logo in the upper-left corner of the page should slide out a navigation from the left side of the page (assuming you have javascript enabled in your browser).
If you don’t have javascript enabled, then clicking the logo will take you to the footer of the page where the basic navigation links are located.
I’m also considering a re-working of the icon to possibly make it more obvious that it opens a menu.
Perhaps something like the “hamburger menu icon” is in order?
The first set of links are the main ones for navigating the site Home, Blog, Articles and Software.
Just below that will be the navigation links for the contents of the current page.
For no other reason than I thought it was neat, I also made it so that the background of each of the Table of Contents entries will be a slightly darker color relative to how far along you are in the page/section.
In the example above, I have already read Getting Closer and First Test Article, and I am ~75% of the way through the Speaking of Long section of the post.
Unfortunately, this won’t work without javascript enabled.
I am still thinking of a way to possibly include the TOC in the page without screwing up the layout too much.
Something to play with later I suppose…
At the moment I am using a combination of serving up the images directly from my host, and using Google+ photos.
Mostly because I have limited space on my webhost, and I’m not quite sure what the impact will be just yet.
I also gain the distributed Google infrastructure for image hosting, which helps I think as images are by far the biggest files to serve for these pages.
I also get on-the-fly image resizing when hosting the images on Google, which is handy while I build things out.
One of the downsides is that the on-the-fly resizing doesn’t produce progressive jpegs, which I thought might help with rendering speeds of large pages (images loading progressively at least show that something is there…).
I think I mentioned it in the previous post The Big Picture that I had done the styling to get images to span the entire width of the page.
In that same post I also demonstrated a means for making embedded videos bigger as well.
It turned out that the same styling worked great for images as well.
Here is the lede image wrapped in a <figure> tag:
A caption to the image in a <figcaption> tag.
I can re-use the styling for the larger video to automatically make the image much larger and centered on the page:
Using class big-vid on the figure.
And, of course, wrapping the <figure> in a <!-- FULL-WIDTH --> tag yields:
Wrapping <figure> with a <!-- FULL-WIDTH --> tag and setting the class to full-width.
This is a photography site, right?!
#### Comparing Images
I still don’t have a great solution for image comparison.
The problem is that ideally I could have an image that shows some results with an easy way to toggle back to a comparison image (before/after for instance).
The current way I am doing it is to toggle the image when it’s clicked on.
If you hover over an image, and the cursor changes to a crosshair, then click on it to compare.
I’m borrowing this from the B&W article I was just working on:
Click on the image to compare to original.
This works across mobile as well but I can’t help but feel it is a bit inelegant.
It is also dependent on javsacript and I don’t know if there is a simple way around this.
At least now, without javascript turned on, everything else still works except toggling to the comparison version.
I’d like to have at least a few good articles ready to go at launch time.
As I said, I’m almost finished with the B&W conversion article, but the question is what to migrate next?
I’m thinking that one of the Open-Source Portrait posts would make a nice article to launch with as well,
or perhaps an update/re-write of using Wavelet Decompose for skin retouching?
If anyone has a preference or suggestion, I’m all ears!
I’m also going to publish an interview with a F/OSS photographer whose work I admire.
Black and White photography is a big topic that deserves entire books devoted to the subject.
In this article we are going to explore some of the most common methods for converting a color digital image into monochrome in GIMP.
What We are Trying to Achieve
There are a few things you should focus on in regards to preparing your images for a B&W conversion.
You want to keep in mind that by removing color information you are effectively left with only tonal data (and composition) to convey your intentions.
By liberating yourself of color data the focus is entirely on the subjects and composition
(this is often one of the primary reasons street photography is associated with B&W).
Conversely, the subjects and composition need to be much stronger to carry the result.
As an interesting side note, Edward Weston’s Pepper #30 is the image that began my personal interest in B&W photography.
Tonality
What I tend to refer to when using this term is the presence and relationship between different values of gray in the image. This can be subtle with smooth, even differences between values or much more pronounced.
When referred to as the singular “tone”, it is usually referring to a single value of gray in the image.
Contrast
Contrast is the relative difference in tones between parts of an image.
High contrast will have a sharper differentiation between tones, while low contrast will have less differences.
Often, a straight conversion to grayscale can result in values that are all similar, yielding a tonally “flat” image.
Contrast is often considered in terms of the entire image globally, or in smaller sections locally.
Dynamic Range
Dynamic range is the overall range of values in your image from the darkest to the brightest.
The Approach
The approach we will take here is similar to what I had done in my film days.
We’ll attempt to use different methods of grayscale conversion (and possibly blending them) to get to a working image that is as full of tonal detail as possible.
Petteri Sulonen refers to this as his “digital negative” – if you want a great look at a digital B&W workflow head over and read his article.
Then, with an image containing as much tonal detail as possible, we will modify it with adjustments of various types to produce a final result that is visually pleasing.
Before heading down that path, it may help to have a closer look at the tools being used.
Let’s have a look at how an image gets displayed on your monitor first.
Your Pixels and You
You are working in an RGB world when you stare at your monitors.
Every single pixel is composed of 3 sub-pixels of Red, Green, and Blue.
300X magnification of an LCD panel.
(Image from wikipedia)
The variations in brightness of each of the sub-pixels will “mix” to produce the colors you finally see.
The scales available in an 8-bit display are discrete levels from 0–255 for each color (28 = 256).
So if all of the sub-pixel values are 0, the resulting color is black.
If they are all 255, you’ll see white.
Any other combination will produce some variation of a color.
80, 205, 255 for instance
or 255, 172, 80
But what about 16-bit images?
Well - the data is still in the image file to correctly describe the colors at 16bit/channel, but most likely what you’ll be seeing on your monitor is an interpolation of the values to an 8-bit/channel colorspace.
You should always work in the highest bit depth color that you can, and leave any conversions to 8-bit for when you are saving your work to be viewed on a monitor.
The important point to take away from this is to realize that when all three color channels are the same value, you’ll got a grey color.
So a middle gray value of 127, 127, 127 would look like this:
127, 127, 127
While this is a little brighter: 220, 220, 220
Very quickly you should realize that a true monochromatic grayscale image can display up to 256 discrete shades of gray going from 0 (pure black) to 255 (pure white),
while for 16-bit images, 216 will yield 65,536 different shades.
It is this limitation for purely gray 8-bit images that introduces artifacts over smooth gradations (posterization or banding) – and is a good reason to keep your bit depths as high as possible.
Getting to Grey
There are many different paths to get to a grayscale image and almost none of them are equal.
They will all produce different images based on their method of conversion,
and it will be up to you to decide which ones (or portions of) to keep and build upon to create your final result.
A combination of luminosity desaturation and GEGL C2G Conversation in Hayleys by Pat David (cba)
For this tutorial we are going to try and cover as many different methods as possible.
This means we’ll be having a look at:
One of these methods may work fine for you.
Or, if you’re like me, it will most likely be a combination of one or more of these methods blended through a combination of layer masking and opacity adjustments.
Desaturate (GIMP)
Perhaps the easiest and most straightforward path to a grayscale image is using the Desaturate command.
It can be invoked from the GIMP menu:
Colors → Desaturate…
There are three options available from this menu:
Each of these options (Lightness, Luminosity, Average) will generate a grayscale image for you,
but the difference lies in the way they interpret the image colors into values of gray.
To illustrate the differences, consider the following two figures.
One is a gradient of red, green and blue from black to full saturation.
The other are overlapping circles of color in an additive mix.
Base RGB gradient of pure colors
Base RGB (additive color) mix
Let’s investigate each of the desaturation options on these test images.
Lightness
The Lightness method will add the largest value of red, green or blue and the smallest value, then divide the result by 2.
½ × ( MAX(R,G,B) + MIN(r,g,b) )
So, for instance, with an RGB value of 100, 20, 210, the equation would be:
½ × ( 210 + 20 ) = 115
Using the Lightness function on our test images yields the following results:
Lightness conversion yields similar values regardless of color
Click to compare to original
This means that one channel is actually ignored in creating the final value.
Average
Average will use the numerical average of the RGB values in each pixel.
⅓ × ( R + G + B )
Averaging, the values will trend darker overall
Click to compare to original
Luminosity
Lightness and Average both evaluate the final value of gray as a purely numerical function without regard to the actual color components.
Luminosity on the other hand, utilizes the fact that our eyes will perceive green as lighter than red, and both lighter than blue (relative luminance).
This is also why your camera sensor usually has twice as many green detectors as red and blue.
The weighted function describing relative luminance is:
(0.2126 × R) + (0.7152 × G) + (0.0722 × B)
This is closer to how our eyes will actually perceive the brightness of each color
Notice the overwhelming contribution from green
Click to compare to original
No one of these methods is necessarily any better than the other objectively for your own conversions.
It really depends on the desired results.
However, if you are in doubt about which one to use, Luminosity may be the better option of the three to more closely emulate the brightness levels you will perceive.
Examples
The image below, Joseph N. Langan Park, is an interesting example to see just how much green influences the conversion result using luminosity. Click through each of the different conversion types to them, and pay careful attention to what Luminosity does with the green bushes along the waters edge.
Click to compare: OriginalLightnessAverageLuminosity
This shot of Whitney shows the effect on skin tones, as well as the change in her shirt color due to the heavy reds present.
In just a Lightness conversion, the red shirt becomes relatively flat compared to her skin tones,
but becomes darker and more pronounced using Luminosity.
Her lips get a bit of a boost in tone in the Luminosity conversion as well.
Click to compare:
OriginalLightnessAverageLuminosity
Channel Mixer
Using Desaturate lets you convert to grayscale based on pre-defined functions for calculating the final value,
but what if you wanted even further control?
What if you wanted to decide just how much the red channel should influence the final gray value,
or to have more control over the ratios and weightings from each of the different channels independently?
That’s precisely what the Channel Mixer will allow you to do.
For the examples below I’ll use a different color gradient test map going from blue to blue HSV gradient, with a gradient to black vertically.
This represents the entire 8-bit colorspace.
Gradient representing all the colors/shades in 8-bit sRGB colorspace.
Click to compare:
OriginalLightnessAverageLuminosity
Take a quick moment to click through the various desaturation methods already mentioned.
The Channel Mixer can be invoked through:
Colors → Components → Channel Mixer…
The dialog will look like this with the test gradient:
The Channel Mixer can be used to modify these channel on a full color image, but we are focusing on grayscale conversion right now.
So check the box for Monochrome, which will disable the Output channel option in the dialog (it’s no longer applicable).
This will turn your preview into a grayscale image.
Warning: Math Ahead
If you checked the Monochrome option, and left the Red slider at 100, then you’d be seeing a representation of your image with no Green or Blue contribution (ie: you would basically be seeing the Red channel of your image):
Basically just the red channel
What this means is that with Green and Blue set to 0, the values of the Red are directly mapped to the output value for the grayscale image.
If you were looking at a pixel with RGB components of 200, 150, 100, then the Value for the pixel in this instance would become 200, 200, 200.
It’s also important to note that the sliders represent a percent contribution to the final value.
That is, if you set the Red and Green channels to 50(%), you would see something like this:
In this case, Red and Green would contribute 50% of their values (with nothing from Blue) to the final pixel gray value.
Considering the same pixel example from above, where the RGB components are 200, 150, 100, we would get:
The astute will notice that the sliders actually have a range from -200 to 200.
So you may be asking – what happens if two channels contribute more than what is possible to show?
Using the pixel example again, what if both the Red and Green channels were set to contribute 100%?
While the Channel Mixer will allow us to set these values, we can’t very well set the grayscale pixel value to be 350 (in an 8-bit image).
So anything above 255 will simply end up being clipped to 255 (effectively throwing away any tones above 255, bad!).
This means that you have to be careful to make sure that each of the three channel contributions don’t exceed 100 between all of them.
50% Red, 50% Green is ok – but 50% Red, 50% Green, and 50% Blue (150%) will clip your data.
This is where the Preserve Luminosity option comes into play.
This option will scale your final values so the effective result will always add up to 100%.
The scale factor from the above example would be calculated as:
1⁄( 1.00 + 1.00 + 0 ) = 0.5
So the value of 350 would be scaled by 0.5, giving the actual final value as 175.
If Preserve Luminosity is active, all the values would be scaled by this amount.
This is not to say that Preserve Luminosity is always needed, just stay aware of the possible effects if you don’t use it.
Speaking of Luminosity
Previously we talked about the function used for desaturating according to relative luminance.
If you’ll recall, the formula was:
( 0.2126 × R ) + ( 0.7152 × G ) + ( 0.0722 × B )
If you wanted to replicate the same results that Desaturate → Luminosity produces, you can just set the RGB sliders to the same values from that function (21.3, 71.5, 7.2):
Replicating the luminosity function
If you’re just getting started with the Channel Mixer, this makes a pretty nice starting point to begin experimenting.
Experimenting
A pretty landscape image by Flickr user Cyndi Calhoun serves as a nice test image for experimentation:
You’ll want to keep in mind the primary RGB influences in different portions of your image as you approach you adjustments.
For instance, this image (not coincidentally) happens to have strong Red features (the rocks), Blue features (the sky), and Green features (the trees).
Keep an eye on the individual channels from getting so bright that you lose detail (blowouts),
or from crushing the shadows too much.
Remember, you want to try to keep as much tonal detail as possible!
So, using the luminosity function as a starting point…
Straight conversion using the luminosity
It’s not a bad start at all, but the prominence of the red rocks in the sunlight has been dulled quite a bit.
It’s a central feature of the image and should really draw the eye towards it.
So the reds could be more pronounced to make the stone pop a little more.
With the Preserve Luminosity option checked, begin bumping the Red channel to taste.
Red channel bumped up to 66.1
(Click image to compare to base luminosity conversion)
This gives a little more prominence to the red stone.
The Green channel seems ok, but for comparison try lowering it to about half of the Red channel value.
Remember – Preserve Luminosity is checked so the final values will scale to give Red values twice the weight as Green.
Green channel at ~half of Red.
(Click image to compare to previous step)
This brings up the shadow side of the central rocks a bit as well as adds some definition to the trees and vegetation.
Also interesting is the apparent boost to the red rocks as well.
If you’re wondering why the red rocks got brighter as well, consider the math.
Previously Red and Green were very near each other in value (around 70), so both colors had approximately equal weight.
When Green got its influence cut in half, Red scaled to take a much larger influence, and because there was more red than green the final value will end up higher.
If we look at the RGB values of the red rocks, the values are roughly like this (ignoring Blue for the moment because for this example it’s staying constant): 226, 127.
If both Red and Green have equal influence, the final pixel value will be:
( 226 × 0.5 ) + ( 127 × 0.5 ) = 176.5
Now if Green is only half as strong as Red, the value will be:
The result was divided by the influence amount to scale the way Preserve Luminosity would.
The final pixel value will become brighter in this case, which is why the red rocks got brighter with a decrease in the Green channel.
It should go without saying that the Blue channel will have a heavy influence on the sky (and many areas of the image in shadow).
To add a little drama to the sky, try removing the Blue channel influence by setting it to 0:
Blue channel set to 0
(Click image to compare to previous step)
This will darken the sky up a bit (as well as some shadow areas).
Pay careful attention to what these changes do to the image in closer views.
In this case there is a higher amount of banding and noise in the smooth sky if values get pushed too far.
So try to approach it with a light hand.
The sliders also allow negative values.
This will seriously crush the channel results when applied (and will quickly lead to funky results if you’re not careful).
For example, to push the Blue channel even darker in the final result, try setting the Blue channel to -20:
Red: 66.1, Green: 33, Blue: -20
(Click image to compare to previous step)
The sky has become much darker, as have the shadow side of the rocks.
There is an overall increase in contrast as well, but at the expense of nasty noise and banding artifacts in the sky.
General Rules of Thumb
The Red channel is well suited for contrast (particularly in the brighter tones).
The Green channel will hold most of the details.
The Blue channel contains grain and (often) a lot of noise.
In skin, the Red channel is very flattering to the final result and you’ll often get good results by emphasizing the Red channel in portraits.
On Skin
The Red channel can be very flattering on skin and is a great tool to keep in mind when working on portraits.
For instance, below is the color image of Whitney from earlier:
Whitney in color
The straight Luminosity conversion is below.
Click on the image to compare it to a version where the Red channel is set equal to the Green channel (giving a greater emphasis on the Reds):
Whitney in Luminosity
(Click to compare Red channel = Green channel)
B&W Film Simulation
Due to the popularity of the Channel Mixer as a straightforward means of conversion with nice control over each of the RGB channel contributions, many people have used it as a basis for building profiles of what they felt was a close emulation to the tonal response of classic black and white films.
Borrowing the table from Petteri Sulonen’s site, these are some common RGB Channel Mixer values to emulate some B&W films.
These aren’t exact, of course, but some people may find them useful.
Particularly as a starting-off point for further modifications.
Film
R, G, B
Agfa 200X
18, 41, 41
Agfapan 25
25, 39, 36
Agfapan 100
21,40,39
Agfapan 400
20,41,39
Ilford Delta 100
21,42,37
Ilford Delta 400
22,42,36
Ilford Delta 400 Pro & 3200
31,36,33
Ilford FP4
28,41,31
Ilford HP5
23,37,40
Ilford Pan F
33,36,31
Ilford SFX
36,31,33
Ilford XP2 Super
21,42,37
Kodak Tmax 100
24,37,39
Kodak Tmax 400
27,36,37
Kodak Tri-X
25,35,40
There’s a good reason that Channel Mixer is such a popular means for converting an image to grayscale.
It’s flexible and allows for a great level of control over the contributions from each channel.
Unfortunately the only way to preview what is happening is in the tiny dialog window.
Even when zooming in it can sometimes be frustrating to make fine adjustments to the channel contributions.
Decomposing Colors
Another method of converting the image to grayscale is to decompose the image into its constituent channels.
When looking at the Channel Mixer previously, there was an option to set one of the RGB channels to 100 (and leaving the others at 0) that would isolate that specific channel.
If you wanted to isolate each of the RGB channel contributions into its own layer, it would be tedious to do manually.
Luckily, GIMP has a built-in command to automatically Decompose the image into different channels:
Colors → Components → Decompose…
Will bring up the Decompose dialog box:
The Decompose dialog
The options available are which Color model to decompose to, and whether to create a new image with the decomposed channels as layers.
If Decompose to layers is not checked, there will be a new image for each channel separately (chances are that you’ll want to start out leaving this checked).
The most important option is which Color model to decompose to.
Up to now we have mostly been considering RGB, but there are other modes that might be handy as well.
Let’s have a look at some of the most useful decomposition modes.
This is the Color mode that we’ve been focusing on up to now, and is usually the most helpful in terms of having multiple sources to draw from.
This separates out the Red, Green, and Blue Channels into individual layers for you (and Alpha if your image has it).
RGB decomposed.
HSV/HSL
Hue, Saturation, and Value/Lightness is another useful decomposition, though usually only the Value or Lightness is useful for B&W conversion.
Hue, Saturation, Value (HSV) Channels
The Value in HSV is derived according to a simple formula:
Value, V = MAX( R, G, B )
Which is basically just the largest value of Red, Green, or Blue.
Hue, Saturation, Lightness (HSL) Channels
The Lightness in HSL is derived from this formula:
Lightness, L = ( MAX( R, G, B ) + MIN( R, G, B ) )⁄2
Where Lightness is simply determined as the average of the largest and smallest component of RGB.
While Hue and Saturation may seem interesting, it should be obvious that the most useful channels for a grayscale conversion here would likely be Value or Lightness.
Overall, Lightness will tend to be a bit brighter than Value.
LAB
There is far too much information concerning the LAB colorspace to really go into much detail here. Suffice it to say that the L in LAB is for Lightness, while A and B are for color opponents (A = Green⇔Red, B = Blue⇔Yellow).
Later articles about color toning will show some neat tricks using the LAB colorspace for adjustments.
The LAB colorspace is based on a perceptual model (similar to the relative luminance previously discussed).
In fact, the Lightness in LAB is calculated using the cube root of the luminance from that function.
LAB Channels
As you can see, the only channel of any use for a B&W conversion is really the Lightness, L channel.
CMY(K)
Cyan, Magenta, Yellow and (Black, K) are often discussed in terms of printing.
When doing the decomposition in GIMP, you’ll have to invert the results to make them useful.
Once you do, you may notice that they are, in fact, the same as RGB (for CMY decomposition):
CMY conversion (inverted from direct conversion)
CMYK produces a similar result, but adds another channel to control the level of black in the result.
Inverting the Black, K channel yields something usable.
CMYK conversion with the Black, K channel inverted
YCbCr
Anyone who has done video processing might recognize this colorspace representation, as it often shows up in digital video.
YCbCr is a means for encoding the RGB colorspace with three channels: Luma, Y, and two channels of Red (Cr) and Blue (Cb) chroma differences.
YCbCr
Try to use the 256 variants of the ITU recommendations to allow the decomposition to span the full 256 values available (the non-256 versions will pad 16 to the range, only allowing values to go from 16-240).
So What’s the Result?
Let’s summarize some of the most useful results from Colors → Components → Decompose for a B&W conversion:
RGB - All channels
HSV/HSL - V (Value) and L (Lightness)
LAB - L
CMYK - K
YCbCr - Y (Luma)
This gives a total of 9 different types of color mode conversions that may be useful for generating a B&W image.
It helps to visually see all of the options at once to get a better feel for what is going on:
All 9 useful channels from Colors → Components → Decompose
Chances are that one of these conversions might prove useful as a direct B&W conversion.
It helps to notice that the first 4 conversions are all color channels, while the last 5 conversions are brightness values based on different functions for achieving the results (K, Value, Lightness, L, Y (luma)).
The Script
I had previously written some Script-Fu to automate the task of generating these useful channel decompositions (it was tedious choosing each color model manually).
The script will take the active layer in an image, and decompose it to each of the useful color channels listed above, each on its own layer.
Once downloaded and placed into your Scripts folder, the command can be found here:
Likely that some parts of some conversions will be useful in some way.
I am personally rarely satisfied with any of the straight conversion options on their own,
but would like to pick and choose which parts of the image contain the best detail and tones from the different conversion options.
The fun is then combining them in such a way so as to produce a final result that is pleasing.
Pseudogrey
Pseudogrey (grey, not gray, per the original author, Rich Franzen) is a means for increasing the available levels of perceived gray in an image using a bit-stealing technique.
The basic approach in Pseudogrey is that you can achieve a much higher number of perceived gray values in an image, if you allow some of the pixels to stray just a tiny bit away from pure gray. For instance, if a pixel value in a true gray image was: 180, 180, 180, Pseudogrey may actually make the pixel value something like 180, 181, 180.
That is, the Green value may be just a bit higher. The full post on Pseudogrey goes into much more detail about the algorithm.
The results from using Pseudogrey will follow the same model as for Luminosity desaturation, but will provide a much larger range of tones (1786 possible shades vs 256 in a truly gray image).
There are a couple of ways to convert images to pseudogrey.
Once the file has been downloaded and placed into your Scripts folder, the command can be found under:
Colors → Pseudogrey…
Alternatively, if G’MIC is installed then the command can be found at the Black & white filter:
G’MIC → Black & white → Black & white
At the end of all of the various options in the filter, there is a Pseudo-gray dithering option to apply the algorithm at various levels (higher levels increase the distance from true gray for each pixel).
Pseudogrey can be helpful in areas with slight tonal value changes over a large area, as this is often where banding will become visible in an 8-bit image.
While the differences may be slight in many cases, if allowing the tiniest amount of color shifting to creep into the image for an expanded tonal range is ok, then pseudogrey is a great option to have.
GEGL C2G
The Generic Graphics Library (GEGL) is the underlying graphics engine for GIMP.
There is one neat function in GEGL specificaly for B&W conversions called Color 2 Grayscale (c2g).
It can be found on the Tools menu in GIMP:
Tools → GEGL Operation…
Rolf Steinort covers c2g briefly in episode 84 of Meet the GIMP.
Paul Bou also looks at using c2g for B&W conversions in a little more detail, and Joel Cornuz also asks if c2g could be the “ultimate” B&W converter.
It may not be worth all the hyperbole, but c2g does do some very interesting things.
The operation considers each pixel relative to its neighbors within a given radius.
The value determined is evaluated as a function of perceived luminance weighted against neighboring pixels.
The description from GEGL.org is:
Color to grayscale conversion, uses envelopes formed from spatial color differences to perform color-feature preserving grayscale spatial contrast enhancement
In practice, c2g will attempt to scale the values of pixels within its neighborhood (radius) to maximize contrast.
What some people like about c2g is that the operation will also introduce a nice range of synthetic grain during the conversion.
There are ways to minimize the resulting grain by adjusting settings, though.
Let’s consider this test image:
Straight Luminosity desaturation in GIMP
At first glance, GEGL c2g will likely produce ugly results.
The default settings are not conducive to producing a pretty image:
c2g conversion, default settings (radius 300, samples 4, iterations 10)
(Click image to compare to original)
The default settings will (usually) produce a nasty halo effect on edges where the radius is not large enough to fully consider transitions.
The edges of the buildings/trees against the sky show this particularly.
There is also an excessive amount of synthetic graininess to the result.
Tweaking parameters can lead to better results at the cost of processing time.
GEGL c2g is not a fast algorithm.
Haloing can be decreased by increasing the radius and graininess can be decreased by increasing the samples or iterations.
Iterations seem to have a larger effect on overall noisiness in the result but (again) at the cost of increased processing time.
Betters results after increasing some parameters (radius 750, samples 8, iterations 15)
(Click image to compare to default parameters)
Increasing the radius helped to alleviate some of the halos and will allow the algorithm to spread the contrast over a larger area.
The increase in samples and iterations helps to keep the noise down to a more manageable level as well.
Refining even further yields slightly better results:
Betters results after increasing some parameters (radius 1500, samples 8, iterations 20)
(Click image to compare to original)
At this point the noise is nicely suppressed while the halos have mostly been eliminated.
The overall image still has more contrast than the straight luminosity desaturation (click to compare) and the contrast has been weighted for the surrounding pixels as well.
If a luminosity desaturation will choose a pixel value based on the perceived color brightness, c2g will do the same in addition to weighting the result relative to neighboring pixels.
For example, below is an optical illusion showing the effect on perceived luminosity relative to nearby brightness:
Square A and B are the same value of gray!
Squares A & B are the same exact shade of gray.
The reason we perceive B as lighter than A is due to the way our eyes are perceiving nearby colors (and our expectations are strengthened by the checkerboard pattern as well).
The results of running the image through c2g aligns the pixel values closer to what our eyes see:
After letting c2g do its thing
This operation can be very handy for bringing out micro-contrasts in an image (or increasing global contrast at large radius settings).
Conversion Examples
Finally, a look at a simple workflow for applying these various methods of grayscale conversion to arrive at a final result.
The overall workflow here will be to decompose the image to various grayscale layers.
Then to investigate each of the different versions to identify features of interest aesthetically.
Finally, combine the different decompositions and mask accordingly to highlight those features or tones.
Pretty Woman
Do a Creative Commons search on Flickr, and it’s very likely that photographer Frank Kovalchek will show up in some fashion. He liberally licenses many photographs under Creative Commons licenses, and we will be using one of his portraits for this first example.
Utilizing the script from earlier to quickly break the image down into multiple layers using different decomposition modes produces a nice array overview to consider:
These various decompositions supply a large amount of possible variations in getting to a finished product.
Keep in mind that the goal in this example is to maintain good tonal density as well as imparting a sense of texture and detail.
The Scarf
As good a starting point as any, consider the texture and detail of the scarf. Looking at the various decompositions in the array, the question you should be asking yourself is:
Which of these results produces the best quality/texture in the fabric of the scarf?
Looking at the previews leads to three possible choices: Luma Y709F, Luma Y470F, and HSL - Lightness.
Of those let’s go with Luma Y709F.
This is very subjective, of course.
The important point to take away is the choice being made due to qualities it possesses for a particular purpose.
The Y709F - Luma channel as a “base” layer - chosen for the fabric texture
The main focus of the image will be the models face but you will still want to retain detail and texture in the scarf as well.
The Skin
Looking at the model and her skin there is already fine detail , but could use a bit more emphasis overall.
Perhaps get the skin a little bit brighter and in a higher key to offset the dark background and the scarf.
It would be nice to smoothen/soften the skin tones as well.
Keeping that in mind, look back at the various decompositions again, this time with an eye towards skin tones and her face.
Not surprisingly, the RGB - Red channel looks very pretty (as well as the HSV - Value).
It’s fairly common that the red channel will be complimentary on (Caucasian) skin.
There is even an old trick to use the red channel as an overlay on a color image to help “enhance” skin tones.
So let’s try that here.
Place the RGB - Red channel over the Luma - y709f channel and change the layer blending mode to Overlay.
Luma Y709F base, with Red channel over (layer blend mode: Overlay)
(Click to compare to base Y709F - Luma)
Visually this appears to have more impact, but the skin may be blown out a little too much.
One option to attenuate this would be to lower the opacity on the RGB - Red layer.
Also, note that very often the visual impact may also be due to the higher contrast in the image at this point.
Sometimes it’s best to stand up and look away from the image for a while before committing to a change…
The problem with adjusting the opacity for the entire layer is that the ratio of levels between the skin and scarf may not be desirable for the final output.
Adjusting the opacity might reduce the effect on the skin, but at the same time will reduce the effect on the scarf by an equal amount.
What is needed is a way to apply the effect stronger on the scarf or skin separately.
This is exactly what Layer Masks are for!
Masks
At this point a layer mask could be added to the RGB - Red layer, and then painted by hand to modify the intensity by isolating the face and giving a little less opacity to the scarf.
It’s a lot of tedious, detailed work.
However, if you look back on the array of decompositions you may notice that channels like RGB - Blue and RGB - Green look pretty good for isolating the face from the scarf already.
So we are going to use the RGB - Green layer and apply it as a layer mask to the RGB - Red layer.
The Layers palette should look something like this in GIMP now:
Keep in mind, a layer mask will be more transparent the darker the color is in it.
The lighter areas will show more of the layer it is applied to.
In this case, the lighter areas will allow more of the RGB - Red layer to show, while darker areas will show more of the layer below, Luma - Y709F.
The results at this point with the mask:
RGB - Red as overlay with RGB - Green as a layer mask
(Click to compare without the layer mask)
What this has done is to isolate the models face from the surrounding scarf.
You can now modify the opacity of the layer, or adjust the values of the mask using Levels or Curves to adjust the intensity of the result.
Any changes to the RGB - Red layer will now be masked to apply mainly to the models face.
Looking at the results, the scarf has become much more flat in tones, while the models face has brightened up.
Considering it, the ratios look backwards a bit. The scarf has flattened out, and the face has brightened a bit too much.
To flip the ratios, simply invert the colors of the layer mask.
Select the mask (not the layer itself!), and run:
Colors → Invert
The layers palette will now look like this:
The result on the image so far:
Inverted mask results
(Click to compare to non-inverted mask)
At this point the results look pretty nice and would make a fine stopping point.
The overlay and mask added some nice depth to the scarf fabric while maintaining a nice effect on the skin of the model as well.
More work could be done if wanted with adjusting layer mask levels and increasing/decreasing the results on the models skin but this looks good as it is.
A final comparison of the results against a straight color desaturation:
Final result
(Click to compare to straight color desaturation)
This path was a little fussier than doing a straight color desaturation but the results are much nicer and is visually more interesting.
Methuselah
Well, this isn’t the actualMethuselah, but it is a similar species of Bristlecone Pine. Once again, image courtesy of Flickr user Frank Kovalchek.
As before, a first look at multiple decomposition modes originally pointed to Luma - Y709F as being a good candidate for the conversion.
In this case, the focus would be on the texture of the tree itself.
The RGB - Green decomposition also looks quite good to use as a base moving forward.
The primary focus is the gnarled old tree itself and the secondary focus the lighting of the sun across the ground.
RGB - Green channel decomposition
While the RGB - Green channel is nice for the tree texture, the sky still appears too bright and the ground could be a bit darker compared to the tree.
The sunlight on the upper branches of the tree and topping the brush on the ground gets slightly lost when the sky is so bright comparatively.
Having found a good layer for the tree texture, the other decompositions are examined for something that represents the sky and ground a little better.
The RGB - Red channel is a good compromise (the RGB - Blue channel is a little too noisy).
RGB - Red channel decomposition
(Click to compare to RGB - Green)
RGB - Red looks like a great candidate for the sky and ground, while RGB - Green will do nicely for the tree textures.
As before, layer masks can be used to modify the mix of the two layers to arrive at a final result.
Set the RGB - Green channel above the RGB - Red channel on the layer palette, and add a layer mask to the RGB - Green channel layer initialized to Black (full transparency).
This lets all of the underlying RGB - Red channel layer show through.
Red channel layer, with Green channel over + mask
Now with the layer mask active (see the white outline around the layer mask, not the layer itself above), paint with a white color to allow that portion of the RGB - Green channel layer to show through.
When painting with white, it will turn the current layer the mask is associated with opaque in those areas – so focus on painting white where the tree is.
Below is a quick mask to illustrate.
It’s only a quick mask, don’t judge it too harshly…
The layers at this point will look like this:
The results from applying the mask above to the image:
Final blend of RGB - Red and RGB - Green channels with mask
(Click to compare to straight desaturation)
This could be a good final version, though there is still a bit of noise in the upper-left corner of the sky from the Red channel.
This could be fixed by adding another layer mask just for the sky which would allow adjustments to the levels of the sky relative to everything else.
Grain
Following some ideas from the great tutorial by Petteri Sulonen on Digital Black and White, he speaks a bit about grain in B&W images.
There are a few different methods of adding synthetic grain to an image but visually the results are less than impressive.
Petteri was kind enough to make available a grain field that he processed himself from scanned film.
An easy way to add grain to an image using this grain field is to add it as a layer over the image, set the layer blending mode to Overlay, and adjust opacity to suit.
100% crop with Petteri’s grain field applied as Overlay layer
(Click to compare no grain)
There are many ways to get to a monochrome image.
The important process to take way from this article is to consider elements of the final image as built up from multiple conversion methods, and controlling/applying them as needed to serve the final result best.
Mix and match the methods presented here to get to the best base for further modifications.
First things first.
I forgot to actually link to the new About page in my last post.
So here it is.
As with all things related to the site, any feedback, comments, or criticisms are welcome!
Speaking of feedback, comments, and criticisms, I wanted to write about it for a moment.
First, I want to thank everyone who has taken the time to contact me and provide me feedback on the site.
You have no idea how valuable it is to both as a motivator, and as a means to know when something is off.
I appreciate and give my full attention to each and every person and idea thrown at me. Thank you!
From the beginning I have been considering how to let everyone interact with the site and posts.
It would be so much easier for folks to leave a comment on a page (or forum) directly.
Particularly if it allows everyone to view the conversation.
One thing I could do relatively easily is just use a third party commenting system, like Disqus.
They make it so easy it almost seems silly not to do it.
An account, a few lines of javascript, and done.
This method comes with a price, though.
A price in both user privacy concerns as well as the fact that comments are no longer mine (pixls.us) to manage and archive.
I don’t know that I’m willing to pay that price yet just for convenience.
If anything, I may set it up as a temporary solution while I work on something a little more long term.
From what I’ve seen so far, Discourse is the long term solution that I would like to get up and running.
It’s also “Yet-Another-Thing” I should thank darix on #darktable for pointing me to.
The only drawback at the moment is that my hosting provider doesn’t have what I need to get it running (relatively easily).
There are a couple of options for hosted solutions that I may go with, but I want to focus on getting the content ready to go for an “official” launch before I get too far down that rabbit hole.
Yes, I know there’s a need for having some sort of commenting system available for everyone to participate!
I’ll get one running just as soon as I can.
I’ve started working a bit on the “About” page for the site.
I wanted a place to highlight the mission statement I’m sort of working from:
To provide tutorials, workflows and a showcase for high-quality photography using Free/Open Source Software.
As well as a place to let users know who is behind the scenes working on the site.
It’s mostly me at the moment, but I’ve managed to talk someone into helping me…
Yep, that’s right.
I’ve managed to talk Rolf Steinort of Meet the GIMP fame into helping me out with the site.
We’re still not 100% sure exactly what this means yet, but I have already been bouncing ideas off him for some of the site details anyway.
Meet the GIMP is over 7 years old now, and quickly closing in on episode 200!
I am excited (and honored) to have his expertise and help as we build this site out.
Especially because my feeble attempts at video productions are sad at best, and Rolf has the type of voice that could read the phone book and I’d still listen to it.
I’m currently in the process of choosing which articles from my archive on Getting Around in GIMP I want to translate over and possibly update/rewrite.
If anyone has suggestions on which ones they’d like to see, you can always let me know.
One other thing that I’m trying to decide on is if I should worry about breaking up long posts into multiple pages or not.
I don’t really have any interest in making users click through multiple pages to get all of the content (I personally hate doing this).
On the other hand, if the post is really long it could take some time to load all the assets if they all exist on a single page.
It may be a delicate trade-off for keeping a page responsive vs. requiring a user to click through to a second (or possibly third) page.
For the moment I’m erring on the side of convenience for the user and keeping things as long pages.
Sometimes I get into weird OCD mode where I need to have something for better or worse.
One of those things was a desire to break out of the mold of standard blog-type posts in articles for this site.
I’ve sometimes found images are relegated to second-class citizens on some page layouts that don’t do them justice.
I couldn’t let that happen here.
The problem was that I needed to do some things to make sure the typographic layouts were visually strong as well.
This meant a adding control to width and layout of main text elements, with the downside of having to hack a bit to make images large.
The solution I ended up with was to add a tag surrounding elements that I wanted to break out of the current layout.
So I would end up with something like this:
<!-- FULL-WIDTH -->
<img src="http://to be full width.png"/>
<!-- /FULL-WIDTH -->
Technically, in my case, I’m using the <figure> tag with <figcaption>, so my actual markup for full-width images looks like this:
<!-- FULL-WIDTH -->
<figure>
<img src="http://full-width-image-src.jpg" />
<figcaption>A caption for my image</figcaption>
</figure>
<!-- /FULL-WIDTH -->
This let me capture that block in my processing when I build the site (metalsmith), and to modify the page code to accommodate what’s needed to make it full-width.
The result of this is that I can now break images out of their containers to span the full width of a page, like this:
A view of Nikolaikirche in Leipzig, Germany.
For you darktable fans, that’s houz in the bottom right.
Of course, this can get very tiring very quickly.
I find that it tends to break the flow of reading, so should be used sparingly and wisely in the context of the post or article.
I promise not to abuse it.
It’s a small thing, but I’ve added an attribution line for the lede images that you’ll find in the bottom right of the actual image.
I will also be incorporating the Creative Commons icon fonts to support proper attribution notice as well.
Once I’ve done that, I will include a similar style attribution for other images (as it stands now, they can be put into the <figure> image caption).
Of course, sometimes what is needed to really explain a concept is to use a video.
So I couldn’t just ignore a way to get good video styling.
My first hurdle was to find a way to keep the video container fluid with the rest of the page.
Remember, the page is built to be responsive, so it’s a single page served to all devices.
This means that I need to adapt to all possible viewing device screen resolutions (as well as possible).
Getting images to scale and resize correctly to fit new sizes was easy.
Doing the same thing for video is not as easy, but wasn’t too bad.
Once again, I’m relying on the kindness of strangers…
The answer came in the form of an A List Apart article from 2009 by Thierry Koblentz.
The basic premise was to create a box to contain the video embed, then to stretch the video to fill the box dimensions.
Then I could still the box to be responsive just like the other elements.
So I wrapped the video embed in a container box, and added some CSS classes:
Then it was just a matter of styling by setting the padding property to be percentage based on th width of the container.
To use a 16:9 ratio, the percentage should be 56.25%:
Et voila! Fluid video embeds that hopefully should maintain responsiveness.
Of course, I couldn’t leave well enough alone, and to coincide with the previous idea of displaying larger images, I have also added a little extra to embiggen video embeds as well (not full width stretching, but to give it a bit more prominence).
Technically I’m stretching the video to 150% of the width of it’s parent container, which happens to be the same container as the <p> elements (so roughly 150% of the text column width).
Mostly I was going to use this type of styling for highlight videos, and leave a normal video embed if it’s not the focus of the article.
Just for reference, a normal (fluid) embed would look like this relative to the surrounding text:
Which makes more sense for supporting material vs. feature videos.
Ok, I could ramble on for longer, but I think my time is better spent getting back to writing the site.
I think the blog back-end and formatting is mostly done at this point, so on to feature articles!
It took a bit of digging and wrestling to get there, but a couple of nights ago I also managed to get an RSS feed working for the blog posts on the site.
Honestly, I spent more time fiddling with dates in javascript than I should have.
I had to make some minor modifications this morning to accommodate where the location should be, but it should be live now.
Both the blog index pages and post pages contain a <link> element that point to it, so most readers should find the feed if you point it at a page.
I’ll test it later, but the most important thing is the location is correct regardless of whatever hacking I do to the feed itself later.
I’ve tested the feed quickly with feedly and it appears to be working ok. If anyone else is using other feed readers and sees a problem, please let me know!
I intend to have a separate feed available for the articles and main site content when I get those ready to go (most likely at http://pixls.us/articles/feed.xml).
I’ve also started (perhaps prematurely?) getting some social media accounts registered.
If for nothing else than to keep someone else from parking the accounts.
At the moment, I’ve got a Google+ page setup for the site.
I’ll try to keep updates flowing to that page as well (so if you happen to use g+, follow it!).
If you already follow me on g+ then you’ll know I’m fairly active there.
Now if I could just get google to allow my vanity URL to only read +pixlus I’d be a happy camper!
Back when I first registered this domain name, I apparently had the foresight to register a Twitter handle as well.
So if you want to follow the conversation there, you can find me @pixlsus.
I even found a first tweet back from Dec 2011!
I feel like I’m gaining a little traction here.
There’s a few more things I need to tidy up and make some design decisions on, but at least I have a clear vision going forward.
I’ve already got an article ported over from Getting Around in GIMP on my blog to use as a test case for formatting.
As soon as I like how it’s looking, I’ll work on porting over some other articles as well.
If it goes well, I may just go ahead and update/re-write some more things as well to test with.
As soon as I have things in a relatively stable state I’ll also get some new material out as well!
So, I’ve had the idea in my head for a while that it would be nice to get the navigation out of the way.
When I’m reading an article or tutorial, I don’t want to be inundated with elements that aren’t pertinent to what I’m reading.
I want to focus on the content.
I had to think a bit on the best way to possibly achieve this.
One option was to remove all navigation from the top of the page, and instead show them at the end of the article.
This runs on the assumption that the user wants to read the page, and when they’re finished reading to possibly navigate somewhere else.
If they came to the page by mistake, or want to get out, they can always use “Back” on their browser.
If they made it to the end of the article, then that’s the point where they may want other navigation options.
(This is how the page is currently laid out).
If they don’t have javascript turned on, they can still use the site just fine.
(This is important for accessibility, and security for some folks).
This is 2014 for the love of Pete!
Surely we can reasonably expect that most users will have javascript?
Well, maybe not.
If they do, however, we might be able to create something slightly nicer.
I personally like the idea of a menu hidden out of the way until needed.
So I put a small floating logo in the top-left of the page.
If you scroll down, the logo should slide out of view (not needed).
If you scroll up, it should bring the logo back into view (possibly needed).
This has already been here since I started building these pages, but now I’ve added a little more…
By default a click on the floating navigation logo will scroll the page to the navigation links on the bottom of the page.
If JS is turned off, the floating logo will always be visible, and when clicked will still get you to the navigation links quickly.
If JS is turned on, though, the floating logo will now “push” the page to the side as it reveals a navigation menu on the left edge of the page.
The first set of links mirror those at the end of the page for site navigation.
The next set of links is a representation of the “Table of Contents” for the current page.
This is anticipation of longer articles being posted soon.
I wanted to have an easier means of navigating long posts.
Try it out!
Clicking anywhere on the main page again will collapse the menu.
There may actually be a pure CSS solution for hiding/showing the menu. The javascript is really only there to manage class states, all of the styling and transition effects are done in CSS.
Honestly, though, I think I’m mostly done for the moment. I may come back and re-visit the pure CSS solution later, but for now I want to shift focus to working on content pages (and the actual content itself!).
My thought process so far on building the site is to minimize any requirements on stuff that’s questionable. I’m only assuming HTML/CSS for the most part.
This is to make sure everything can still be accessible to folks.
So the addition of basic navigational elements was a no brainer, but that menu bar looked awfully sparse.
So, I used the extra space to include a “Table of Contents” for the current post/article as well. This is generated automatically from all of the HTML heading tags in the page (h1/2/3/4/5).
My intention at the moment is to also have some sort of a reading progress indicator show up along the TOC.
I think this could provide nice visual feedback to users on where they are in an article, and how far along they might be.
Again, this is something that should degrade just fine in older browsers/no-js. Those users simply won’t see the effect.
This is just a log of reference material for actually building this site. It’s mostly for my own reference and edification. If you’re reading this, good luck making sense of my notes…
Static Website with Node.js and Metalsmith
I decided to build this site as a static website. This means that I’m generating all of the material on my local machines, and then compiling them into static webpages that are then uploaded to the server for serving. While this does sound like a pain in the ass, there are static site generators that make this job much easier.
So I looked around a bit more and found that apparently static site generators are the hip new thing.
I originally started with http://nanoc.ws/. While this was pretty interesting looking, I am just not a Ruby guy. So I had the double-whammy of learning the static build system along with Ruby occasionally. Plus, after a host of problems getting the correct ruby and gems installed on my OSX machine I just decided it wasn’t worth the hassle. (I have to switch between win at work, and OSX/Linux at home - so I needed a consistent environment).
I expanded my search and finally remembered Node.js. Looking around a bit more and I also found a static site generator for Node.js called Metalsmith.
This was good, as I was already reasonably familiar with javascript.
Metalsmith basically just takes a directory of files, and passes them into a javascript environment for processing and output to a new directory, ready to be uploaded to a server.
This is how this page is being generated right now as well.
Installing the Build Tools
The first thing to do is to get Node.js for your platform. Once installed, you’ll have access to the commands node as well as npm (node package manager?).
Installing Metalsmith from there is as simple as:
node install metalsmith
Basically, Metalsmith just passes each of the directory contents through a stack of functions that you can use to process the files. Many of these are available as plug-ins for Metalsmith.
For this site so far, I’ve been using these plug-ins:
The structure of this site is still in flux.
By default metalsmith will look for a folder in the project root called “src”, and will output to a folder called “build”.
The site structure I have setup for this site is:
There are a couple of other things I am doing for the templating, and one custom function I wrote to automatically hyphenate url’s. To avoid something like:
articles/a%20new%20article/
I think this looks nicer:
articles/a-new-article/
Honestly, if I was just testing things out, the bare minimum I could use to get by would be:
Test porting one of the ‘Getting Around in GIMP’ articles
Working on it.
Port a few other test articles
Use collections in Metalsmith to collect articles of a type
Generate a page of those.
Probably a new index.html/front page.
Work on “About” page
Finish styling article pages.
Particularly the links (Mobile is done? - Tablet is needed).
This list will grow, of course, as it needs to until we launch!
Blog
I’ve started an article to represent blog posts on the site.
I intend for them to live at the path: pixls.us/blog/YYYY/MM/title-of-post
The problem is that I can’t easily use metalsmith-permalinks for them.
There doesn’t appear to be a way to easily process a sub-folder of documents with a different path.
I don’t want the articles content to contain YYYY/MM in the path, but I do for blog posts.
So I think I’ll just have to write a plugin to handle that myself real quick.
Shouldn’t be too hard, just need to do something similar to what I already wrote for hyphenating urls.
Basically, grab all blog posts, update their paths to the hyphenated version and change the source file to index.html in the directory. IF the file is not already in a sub-directory.
For the curious, and to serve as an introduction, I thought I’d make a few notes about how this site is built and what I’m currently obsessing over.
Hopefully this can help define what I’m up to in case anyone wants to jump in and help out.
The entire point of this site, its “mission statement” if you will, is:
To provide tutorials, workflows and a showcase for high-quality photography using Free/Open Source Software.
Subject to revisions, of course, but mostly sums up what I’d like to accomplish here.
I also think it’s good to have this documented somewhere to remind me. :)
I had already started writing about this elsewhere, but I’m going to reiterate it here for posterity (when I wrote it earlier I hadn’t completed the blog portion of the site yet).
On the recommendation of darix on the #darktable irc channel, I looked into static site generators.
I was originally going to use some sort of CMS and build things out from there, but I have to thank darix for causing me to pause and to think carefully about how to proceed.
I realized that I wanted to keep things simple.
The main focus of the site is the articles themselves (a tutorial, workflow, or showcase).
Really, this content is static by nature - so it made sense to approach it in that light.
The idea is to have all of the site content exist locally on my machine, then to pass it through some sort of processor to output all of the website pages ready to upload to my server. I was already familiar with the process as the GIMP website is built in a similar fashion.
I just had to find a static site generator that I could use and extend as needed.
There is a plethora of static site generators out there (apparently it’s the hip new thing?), so I just had to find one that I was comfortable with using and extending.
I needed it to do what I wanted and get the hell out of the way so I could focus on content.
Oh, and I had to be able to extend it as needed myself. I’m already pretty comfortable writing for the web, so I decided to go with the Node.js-based Metalsmith.
Mostly because I’m already comfortable making a mess in javascript.
Metalsmith basically takes a directory full of data, and passes those objects through any series of functions I want, munges them somehow, and then spits out my website.
It’s the munging part that’s fun, and at least I can extend/modify things as needed quickly and easily.
tl;dr: I use javascript to process the files and output the website ready to upload.
I also wanted the site to work well across different screen sizes and devices.
So I’m trying to incorporate some responsiveness in the design.
You can actually see it working right now by resizing your browser width.
The page should reflow and elements change size to adapt to the new viewport.
This lets me focus on the content while knowing that it should adapt as needed to the viewer.
As a great starting point, I used Adam Kaplans Grid.
Taking a cue from the past, I’m also trying to maintain legibility and readability in the pages.
This means paying attention to simple things like characters per line, font choices, and spacing.
I’m not a designer, so this topic has been fun to learn about as I go.
The lines on this post, for instance, should settle in around 60-75 characters per line (I’m aiming for about 65).
The Baymard Institute has a nice summary of the idea behind this.
This goes without saying, I think, but who wants to look at an ugly layout/site?
I can’t say this site is beautiful, but at least I’m conciously trying to make it a pleasant experience…
If not for everyone, at least for me…
Attractive to me. Possibly to others, but definitely to me!
All the pretty in the world won’t fix something that’s hard to use.
So I’m trying to put thought into user interaction.
I try to get cruft out of the way so the focus is on the articles, while also providing easy navigation or interaction (that should get the hell out of the way when it’s not needed).
That’s the short version.
There’s a million things going on right now in my head as I build the site out.
I’ve got most of the pieces sorted out, and just need to finish assembling them in a way that I like.
So we should be ready to get things kicked off before too long!
Let's see if I can get this thing off the ground...
Well, technically this isn’t the first post on the site.
I had actually started with building out the temporary Coming Soon page.
Then I shifted focus on styling the main content page for the site (articles).
After a bit I realized that I should probably be working on some sort of blog posts as a means for folks to keep up with what I’m doing.
I’m an occasional photographer and I dabble in digital artwork occasionally as the mood strikes me.
I also happen to be a fan of free software. Those two worlds collide fairly often, and lately I’ve been having a great time writing about them.
I’ve been writing tutorials on my blog as well as trying to modernize/update tutorials on the GIMP website.
You could call me a (small) part of the GIMP team (but I’m trying to do more!).
I also try to help out where I can on other F/OSS projects as well (G’MIC is another place you’ll find me bumming around).
I do these things because I think it’s important to try and give back to the community in whatever way you’re capable of.
I’m loud. So I figured I could use that capability to help out.
Well, I mentioned on the main page that I felt like we could use a site/community dedicated to photography. Particularly Free/Open Source Software and photography.
The problem I noticed is a lack of sites that focus explicitly on photography and workflows using F/OSS tools.
There are plenty of blog posts on various sites, forum posts on various boards, and the occasional group on social media.
There is not a great website to act as a portal specifically for photographic needs or interests.
It’s my sincere desire that I can build it.
I actually find it strange to write that.
How does this not exist already?!
I’m building this entire site from scratch, so it’s taking a little bit of time.
I only just got the blog portion finished, so hopefully that much is done.
I’ve also mostly finished what the main articles will look like.
I’m in the process of porting over some of my tutorials from my blog to here so that I can have some content to test things out with.
I enjoy doing this sort of thing, so it’s a nice way to relax for me.
After that I’ll just need to get a couple of other pages setup, and I should at least have the skeleton of the site up and running.
I promise, as soon as I have something to actually launch I will be loud and annoying about it.
Yes, absolutely.
Just shoot me an email and I’ll be happy to answer any questions I can.
If there’s some particular skill you’d like to bring, I’m all ears.
If you want to write an article or tutorial, let me know.