Before and after using the plug-in

After finishing my post-processing experiment, I found myself with a backlog of sketchnotes that needed to be scanned and post-processed. Contrary to what I thought during the experiment, I had the need to automate as much as possible. I have a long history of using Python on and off, so creating a GIMP Python-fu script wasn’t the biggest hurdle.

The plug-in

The script follows the steps that are outlined in the conclusion of my experiment with sensible defaults. It also sets up my brush and colors in a way that makes it possible for me to create consistent results. It simplifies my workflow to:

  • Load the scan into GIMP;
  • Run the plug-in from Image->Prepare sketchnote…;
    • If detail is lost (e.g. near the page fold, or lines that disappeared) then undo and re-run with an adjusted Threshold low value;
  • Rotate and crop the image;
  • Select the layer with the adjusted scan and clean up with a Pencil and a white foreground color;
  • Select the “Grey accents” layer and use the grey color that is preset by the plug-in to add some accents;
  • (Optional) Select the “Color accents” layer, choose a new foreground color, and add the final accents.

If you want to try it out, save the script in the plug-in directory (as e.g. ~/.gimp-2.8/plug-ins/python-fu-setup-sketchnotes.py) and make the file executable. The plug-in should appear the next time you start GIMP.

Without further ado, here’s my first foray into scripting the GIMP:

#!/usr/bin/env python

#
# A GIMP plug-in to quickly clean up a scan of a (B&W) sketchnote (or other documentation) and set it up for further processing
#
# Save this as e.g. ~/.gimp-2.8/plug-ins/python-fu-setup-sketchnotes.py and make the file executable.
#
# The framework of this script was inspired by:
# - https://jacksonbates.wordpress.com/python-fu-gimp-scripting-tutorial-pages/
# - http://www.ibm.com/developerworks/library/os-autogimp/index.html
#

from gimpfu import *

def setup_sketchnote(image, drawable, USM_radius=5, USM_amount=1.0, threshold_low=148, blur_width=2):
    # set up undo group
    pdb.gimp_image_undo_group_start(image)
    # Apply USM 
    USM_threshold = 0
    pdb.plug_in_unsharp_mask(image, drawable, USM_radius, USM_amount, USM_threshold) 
    # Apply Threshold
    threshold_high = 255
    pdb.gimp_threshold(drawable, threshold_low, threshold_high)
    # Apply Gaussian blur
    pdb.plug_in_gauss(image, drawable, blur_width, blur_width, 1)
    # Add a "Grey Accents" layer, 80% opacity for a bit more "fluid" effect.
    opacity_100 = 100
    opacity_80 = 80
    layer_position = 0
    layer_c = pdb.gimp_layer_new(image, image.width, image.height, RGBA_IMAGE, "Grey accents", opacity_80, DARKEN_ONLY_MODE)
    pdb.gimp_image_insert_layer(image, layer_c, None, layer_position)
    # Add a "Color Accents" layer
    layer_g = pdb.gimp_layer_new(image, image.width, image.height, RGBA_IMAGE, "Color accents", opacity_80, DARKEN_ONLY_MODE)
    pdb.gimp_image_insert_layer(image, layer_g, None, layer_position)
    # OPTIONAL set the brush size to 50 (personal preference)
    # and fg / bg color to white and grey
    pdb.gimp_context_set_brush_size(50)
    pdb.gimp_context_set_background("#bbbbbb")
    pdb.gimp_context_set_foreground("#ffffff")
    # end undo group
    pdb.gimp_image_undo_group_end(image)

register(
    "python-fu-setup-sketchnote",
    "Prepares a scanned sketchnote for cleaning and coloring",
    "Prepares a scan of a B&W sketchnote (or other drawing) for cleaning and coloring. First it converts the image to strictly black and white values, while clearing as much irregularities (e.g. ink that bled through the page) as possible. Finally it adds layers for color/grey accents.",
    "Alrik Lubbers",
    "Alrik Lubbers",
    "2017",
    "<Image>/Image/Prepare sketchnote...",
    "RGB",
    [
 #       (PF_IMAGE, "image", "Image", None),
 #       (PF_DRAWABLE, "drawable", "Input layer", None),
	(PF_SLIDER, "USM_radius", "USM Radius", 5, (0, 500, 0.5)),
	(PF_SLIDER, "USM_amount", "USM Amount", 1.0, (0, 10, 0.1)),
	(PF_SLIDER, "threshold_low", "Threshold low value", 148, (0, 255, 1)),
	(PF_SLIDER, "blur_width", "Gaussian blur width", 2, (1, 10, 1)),
    ],
    [],
    setup_sketchnote )

main()

I hope this helps you find your post-processing sweet-spot.

More tk