Diff'ing images in Git

I use Git on the command-line usually, but lately I’m using more and more of git-cola. It’s compact, keyboard-friendly, regularly updated, features a clean UI with main focus on staging and diffs. It was while working in git-cola merging over 100+ files from two different branches that I discovered quite a few overlapping image files. The diff panel was useless and it’s not like I can rely on the command-line for non-textual diffs. Did what every developer does nowadays when faced with an issue, I googled side-by-side diffs, git diff images and any other combination of words and phrases I could come up. There wasn’t much, if anything, useful that came up in the results so I got to work.

I run Ubuntu and Gtk immediately came to mind. It shouldn’t be too difficult to display the two images with their dimensions side-by-side in a window. I don’t need fancy image view modes, just having the two images next to each other would give me enough information to decide which one to accept. At the end, having never done any PyGtk programming before, I came up with a 50-line script that does just what I need:

It’s not an ultimate solution. It will choke up on large images, it doesn’t handle transparency well and there are no controls like zooming in/out, but it is better than nothing.

Overall, I found the PyGtk documentation very easy to read, there are plenty of tutorials around and the API reference has all the information one needs.

Tip: in git-cola, <C-D> will open up the configured diff tool for the highlighted file.

pacman -Syu barfs error: XYZ: signature is unknown trust

Things kept getting better and better. Following the recent pacman upgrade, I was now facing issues with regards to package signatures. I had already successfully completed the keyring initialisation and I was a bit stumbled as to what exactly I was doing wrong.

You remember all those /etc/config saved as /etc/config.new messages. Yes, as it turns out these are important. Given you haven’t modified your pacman configuration (perhaps added to the HoldPkg list recently?), you can safely accept the new values:

$ [sudo] mv /etc/pacman.conf /etc/pacman.conf.pacprev
$ [sudo] mv /etc/pacman.conf.pacnew /etc/pacman.conf

Re-run [sudo] pacman -Syu and you are on your way.

Not enough random bytes available.

Please do some other work to give the OS a chance to collect more entropy! (Need more bytes)

I decided to upgrade pacman on Arch Linux recently. I was advised to run [sudo] pacman-key --init after the update had finished. Sounds simple enough, just one extra command I need to copy -> paste to get me going again. Wrong. It turns out gpg will go about generating a very strong key (did not investigate the exact key size). On my not-so-busy machine it would just sit there doing (what would appear as) nothing for hours. To generate entropy, /dev/random is used. I started:

$ cat /dev/random

in a remote session and there was nothing printed on-screen, e.g., nothing was being generated, e.g., no entropy, e.g., no gpg joy. What follows is a very ugly hack to speed things up. Keep the above remote connection open and connect to the machine in a separate tab/window. Start pacman-key as instructed earlier. Leave the window/tab open and connect again, in a third, separate window/tab. Repeat (many) times:

$ ls -R /
$ [sudo] sync
$ sudo tee /proc/sys/vm/drop_caches <<< 3

Ugly, I know.

Ubuntu 11.10 - Replace the Default (and Annoying) Orange Scheme

Switching to Ubuntu 11.10 is painful, ugly and time consuming… but more on that some other time.

I was quite surprised to see most of the theme control options are now gone. The Appearance panel has no colour tweaks and I hate the default orange scheme. Luckily, there is a way to change it in Gtk3:

$ sudo apt-get install dconf-tools
$ dconf-editor

Browse to org.gnome.desktop.interface. Locate gtk-color-scheme. Edit the property:

bg_color:#f0f1f2;selected_bg_color:#4677f0

Change the colours to your liking. You may need to re-launch some apps for changes to take effect.

…now if I could only get those Gnome Terminal tabs to look darker.

Compass Magick Tutorial - Part 2

There is more to Compass Magick than gradients and borders. In the second part of the tutorial series, we will go through the steps to create a simple 3-state button with an icon.

Recap of Part 1

In Part 1 we completed the tutorial with a simple button-like shape:

Example 4

We generated the shape using linear gradients, corners and borders from Magick:

// intro.scss
$theme1: red;
$theme2: maroon;

$button_width:  320px;
$button_height: 24px;

body {
  background: transparent magick-canvas($button_width, $button_height,
    magick-fill(
      magick-linear-gradient(
        $theme1,
        $theme2
      )
    )
    magick-corners(10px)
    magick-border($theme2, 10px, 1px)
  );
}

To ensure we can easily change the theme colours, we introduced two $theme variables at the top of the file.

Adding an Icon to the Button

Pick an image and save it in your images_dir as icon.png. If you skipped Part 1 of this tutorial, make sure you have a directory named images in your project’s root and add the following line to your Compass configuration:

# Add to config.rb
images_dir = 'images'

Magick comes with a very handy magick-compose function which allows us to put one canvas on top of another. We cannot pass the image file directly to magick-compose as it will refuse anything other than a canvas object:

// This will NOT work
magick-compose('icon.png')

You’ve seen how to create a blank canvas using the magick-canvas function. We can also initialise a canvas object in several other ways, one of which includes the option to load a file from disk:

// Loads icon.png and returns a Base64 encoded Data URL
magick-canvas('icon.png')

Let’s put the two together for a working solution:

// Loads icon.png and uses it as an overlay
magick-compose(magick-canvas('icon.png'))

Adding the above line to our button code:

// {intro => button}.scss
/* …snip… */

body {
  background: transparent magick-sprite('button', magick-canvas($button_width, $button_height,
    /* …snip… */
    magick-compose(magick-canvas('icon.png'))
  ));
}

Yields the following result:

Example 5

It’s not exactly what I would call pretty so let’s make some changes to the dimensions and colours of the button:

// button.scss
$theme1: #3060bf;
$theme2: #5ca1e5;

$button_width:  280px;
$button_height: 32px;

/* snip */

Example 6

The CSS background-position property allows control over where a background image appears inside its container. magick-compose gives us similar control. To offset the icon 5px horizontally and center it vertically, we pass 5px, 50% after the canvas object (note arguments are comma-separated):

// button.scss
/* …snip… */

body {
  background: transparent magick-sprite('button', magick-canvas($button_width, $button_height,
    /* …snip… */
    magick-compose(magick-canvas('icon.png'), 5px, 50%)
  ));
}

Example 7

Applying Effects

Magick packs several pixel-based effects - fade, brightness, contrast, saturation, vibrance and greyscale. We apply them to a canvas object just like we would apply borders or corners:

magick-effect(fade, 50%)

The first argument selects the desired effect and the second one adjusts its strength.

For this tutorial, let’s tune down the icon by making it semi-transparent and reducing the colour intensity:

/* …snip… */
magick-compose(
  magick-canvas('icon.png',
    magick-effect(fade,      50%)
    magick-effect(greyscale, 50%)
  ),
  5px, 50%
)
/* snip */

Example 8

The effects are applied to the canvas we are composing on top of the button shape. If we move magick-effect to the top-level canvas (where borders and corners are applied) then the entire button will be semi-transparent - not what we are after.

Sprites, the Compass Way

We are building a 3-state button. So far we have only constructed the code for our normal state. For the hover state, we simply remove the effects applied on the icon earlier. For the active state, we invert the gradient so the button appears pressed.

We could save the three states as three different images, but this is not good practise and it will result in three requests to the server.
The latest release of Compass offers an easy-to-use spriting support. You import the different button states and Compass takes care of the rest.

Let’s start by moving our button code from the body CSS selector to a $button_sprites Sass variable.

// button.scss
$theme1: #5ca1e5;
$theme2: #3060bf;

$button_width:  280px;
$button_height: 32px;

$button_sprites: magick-sprite('button', magick-canvas($button_width, $button_height,
  magick-fill(
    magick-linear-gradient(
      $theme1,
      $theme2
    )
  )
  magick-corners(10px)
  magick-border($theme2, 10px, 1px)
  magick-compose(
    magick-canvas('icon.png',
      magick-effect(fade,      50%)
      magick-effect(greyscale, 50%)
    ),
    5px, 50%
  )
));

body { }

If we look at the generated CSS, it should be an empty file since there isn’t any code in the body. However, button.png is still generated in images_dir which is what we are after.

Before we proceed to out hover state, let’s rename the generated sprite from 'button' to 'button/normal' which will generate a file button/normal.png. This naming convention is compatible with Compass spriting.

For our hover state, we copy the code for the normal state and remove the effects on the button icon. Append the code to $button_sprites:

// button.scss
/* …snip… */

$button_sprites: magick-sprite('button/normal', magick-canvas($button_width, $button_height,
  /* …snip… */
)) magick-sprite('button/hover', magick-canvas($button_width, $button_height,
  magick-fill(
    magick-linear-gradient(
      $theme1,
      $theme2
    )
  )
  magick-corners(10px)
  magick-border($theme2, 10px, 1px)
  magick-compose(magick-canvas('icon.png'), 5px, 50%)
));

body { }

We end up with two files: button/normal.png and button/hover.png.

Finally, copy the code for the hover state and play with the gradient stops to achieve a pressed button look. Append the code to $button_sprites again:

// button.scss
/* …snip… */

$button_sprites: magick-sprite('button/normal', magick-canvas($button_width, $button_height,
  /* …snip… */
)) magick-sprite('button/hover', magick-canvas($button_width, $button_height,
  /* …snip… */
)) magick-sprite('button/active', magick-canvas($button_width, $button_height,
  magick-fill(
    magick-linear-gradient(
      darken($theme2, 10%),
      mix($theme1, $theme2)
    )
  )
  magick-corners(10px)
  magick-border($theme2, 10px, 1px)
  magick-compose(magick-canvas('icon.png'), 5px, 50%)
));

body { }

We are now ready to create a single image for our 3-state button. It is as easy as adding an import line above the body:

// button.scss
/* …snip… */

@import 'button/*.png';

body { }

Example 9

Using the Button Sprite

The final step is to turn an <a> element into a button:

a {
  display: block;
  width: $button_width;
  height: $button_height;
  line-height: $button_height;
  text-align: center;
  text-decoration: none;
  color: #fff;

  @include button-sprite(normal);

  &:hover  { @include button-sprite(hover); }
  &:active { @include button-sprite(active); }
}

The button-sprite mixins are generated by Compass and allow us to easily switch the background-position property to select the desired button state. The result is:

Conclusion

There are many more features available in Magick. Check out the list of all available commands for a comprehensive reference.

Leave a comment if you have any questions or suggestions and visit the official Github page of the project for up-to-date information and links to other resources.