In preparation for the coming Luddite revolution, I am training myself as a mentat.

<< Previous Page :: Next Page >>

Guest-Starring in Today's Doomed to Obscurity: Yakov Smirnoff and Kent Brockman

Date/Time Permalink: 09/07/09 03:51:18 pm
Category: Graphics Tutorials

I tried something new with Doomed to Obscurity today. See if I can import a couple of characters and have them turn out recognizable, while still drawing in the strip's own style. The first is the real-life Russian-American comedian Yakov Smirnoff, and the second a supporting cartoon character, Kent Brockman from The Simpsons.

The results were uncanny enough to surprise me.

Yakov Smirnoff

Kent Brockman

Things I've learned today:

  • Importing a real live human into a cartoon is harder to do and have them turn out recognizable. As you can see, I combined two images of Yakov to be sure I had as many wardrobe cues as possible, so he's more recognizable to modern audiences.
  • Importing a Simpson's character, on the other hand, is a snap. I have noticed that there are only a few differences between my style for this strip and The Simpsons, albeit with radically different methods.

However, the differences with the Simpson's character are most telling about technique. The Simpsons are drawn in freehand style, so they can be drawn from different perspective than my rigid eye-level three-quarter. I don't do the "beer gut" style of fat belly well, because my shirt and pants are two separate polygons - harder to get a smooth curve right on the belt-line. In the original Simpsons version, the belly is drawn first as a smooth circle, then a line added and colored in last. On the other hand, my computer-polygon environment allows for more precise detail, so I usually draw four fingers. I did three here just to make it look more Simpson-y.

Also, for some strange reason, I can never bring myself to draw really big fat legs. I *could* if I wanted to, but they just seem to gross me out for some reason.

Well, that wasn't very important, was it?

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Inkscape Tutorial - Raised Lettering Effect

Date/Time Permalink: 01/26/09 01:18:29 pm
Category: Graphics Tutorials

A while back I saw a search come in for "Inkscape bump-map". While a bump-map filter as such does not exist in Inkscape, there is a way to get shapes to have a raised 3D appearance. We'll use lettering for this example.

Start with a large canvas - I'm using 800x800 here. I have Inkscape's name written here in the canvas font at 144 point-size, and I increased the size some more after that. We'll see why size is a factor later.

Set the font to the darkest shade of the color you're going to use. With the shape still selected, Ctrl-D to duplicate it. Now set the color on this duplicate to just a shade lighter. Next, we're going to create a "path inset" - to do this, hit "Ctrl-(" - hold down the control, shift, and 9 keys to get the left parenthesis. You only need one inset step at a time, so only hit it once. Then, use the arrow keys left and up to nudge the lighter, inset shape slightly to the upper-left corner of the darker bottom shape.

screenshot 1

Now we just keep repeating these four steps:

  • Duplicate the shape.
  • Set the color lighter.
  • Inset the path.
  • Move it up and left.

For about five or so iterations. Our last step is to repeat this one more time, but go a couple more shades lighter and inset the path two or three times, to give a highlight effect. When you move this layer, hold the Alt key down to get it to move in smaller steps.

screenshot 2

You'll notice by now that most of the shape disappears when you inset it. This is why you start with a shape much larger than what you'll need, because it would be very difficult to make the inset take this many steps at a lower resolution.

This next step's optional if you want a shadow. Select the darkest, bottom layer and Ctrl-D to duplicate, then move it up out of the way of your text. If it isn't a path already, hit Ctrl-shift-C to turn it into a path. With this path selected, pick "effects - generate from path - blur edge".

screenshot 3

You should set this dialog to about a blur width of 5.0 and steps of 5. Hit OK, give it a minute, and it will finish with the shadow on top of the path. Select the shadow (it is automatically grouped from a stack of lighter layers, similar to how we did our highlight), hit the 'End' key to move it to the bottom layer (so it will be behind the letters) and move it down. Move it slightly to the right and a little lower so the shadow agrees with the letter's highlighting. You can also delete the other path copy.

Drag a selection box around the whole thing and hit Ctrl-G to group it all together, then shrink it down (either the left-angle bracket key "<" or the 'transform' dialog's 'scale' tab). You're done!

When you export a scaled model to a flat image file, you get this:

finished raised lettering

This technique gives the bump-mapped and shadowed effect you would use to give a 3D appearance to a shape in a raster editor, but with a much crisper, more defined look. For making the layers blend a little better, you can also set the transparency lighter for the fill colors of the top layers.

Ta-ta, for now...

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Producing an EBook Cover With POVRay and Inkscape

Date/Time Permalink: 12/03/08 06:49:52 pm
Category: Graphics Tutorials

This is going to be half-tutorial and half-exhibition, for at least the intermediate graphics artist.

In selling ebooks, even though you're buying an electronic document that exists only in the virtual world, sellers prefer to market the book with a graphic of the book as if it were a physical object. Which has given rise to a small market for ebook cover design and renders. Here, I've produced a hypothetical example:

sample ebook

So I'll just walk you through the steps. It isn't worth pinning it down in detail, because that might change for an individual project. You might draw the cover and spine in something besides Inkscape, you might need a different size, and you might want to show a paperback or a spiral-bound book or some other design. I'm also going to use KPOVModeler and show how to do it in the GUI, since my usual POVRay tutorials degenerate into a gobbledegook of code which I'm not sure if that's lost on anybody or what. So let's try reaching the visual learners this time.

So I first draw the cover and the spine as PNG files which have dimensions of 765x990 and 100x990. Here's the aspect, chosen to mimic A4 letter size paper, and a book of about 100 pages or so:

aspect of cover and spine

But they're actually saved as two separate files. Now in POVRay, we're simply going to shape a book out of a few polygons and use the two images as textures for the front and side. Let's try to get KPOVModeler showing it. Start with a merge of a box and a cylinder.

book step 1

The two objects are textures with the flat images we made earlier.

book step 1 texture

Next we're going to cut a slice out of those two merged objects with another box.

book step 2

Last, we put another box inside of the sliced-out box and color it white. This will be our "pages" object. We could go to a lot of trouble and use a texture on top of the white block to look more like paper pages and we could also add some detail inside the top of the spine to make it look like it has binding. Those are all more painstaking details. We'll forget that here.

book step 3

Now comes the really hard part. If we just slap a white-colored plane for the book to sit on and use a default light and camera, we get this:

don't do this

God, that's terrible! To fix things so they're realistic, let's give the plane a texture instead. It will still be pure white, but with the addition of a finish which will have these tweaks:

  • ambient color: a neutral gray
  • diffuse: 1.5
  • reflexion: set the maximum to a slightly less than black shade. We only want to reflect enough light to give it a gloss, not make it look like a mirror.

The next fix is to eliminate the horizon, so we make a huge cylinder around the whole scene, camera, book, light, and all. We want an endless sea of uniform white, just like if we had a studio backdrop. We give the cylinder the same texture as the plane.

book step 4

Now we have this:

some progress

The next thing is to soften the shadow. Look around you now: you never really look at the edge of a shadow again in quite the same way after you start 3D modeling. Let's make our point-light be an area light, with many light-points spread out over a disk shape.

book step 5

Your light in the preview windows now looks like a mesh. Every intersection of that mesh represents a light source. In fact, we're making a round disk of light-emitting objects which is more like our real-world bulb. We're almost there:

almost there

One thing you'll notice is that the render takes about ten times as long to finish! That's because your computer's doing many times the work, tracing a lot more rays than it was before.

One more thing we'll do is illuminate the spine with a second light. This time, it's a plain point light, with the color set to neutral gray - the concept is called a "fill light". We're just filling in the shadowed part of the spine so you can see it, but not making it strong enough for the book to cast two shadows.

book step 6

And now for the last tweak, we're going to create a render mode that is 1600x1200, quality 11, antialiasing set to 'recursive', threshold 0.1, depth 8, turn on 'jitter' set to depth 2, and turn on radiosity. Oh, boy, is that ever going to take a lo-o-o-ong time, even on a fast machine! Go take a coffee break or even a nap; on a slower machine I just leave it rendering overnight.

When it's done, save it, then open it in Gimp and crop it down to usable size. I'd recommend saving it as a high-quality PNG, that way it will stay crisp until you're ready to use it. Scale it down and put it next to your order button on your sales page, you crafty Internet entrepreneur, you!

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Blender 2.46 Tutorial - Boning

Date/Time Permalink: 11/03/08 09:46:10 am
Category: Graphics Tutorials

It occurred to me that with all my graphics tutorials, I have never done any Blender ones. This is because, like everybody else including half its user base and even possibly a few of its coders, I barely understand Blender myself. However, I've gotten stupidly overconfident enough to think I can pull off at least one tutorial. So this will be about boning. Now, some call this "armatures" and some call it "linking" and "rigging" and other colorful metaphors and euphemisms. I call it "boning". You're taking a model and putting the bones in. OK?

Blender ss

So, here's my human model, imported from MakeHuman. I've managed to give her something that resembles hair if you don't look too hard and even labored mightily to imbue her with a facial expression. She'll be volunteering for today's tutorial. However, since boning a whole body will be too complicated for this tutorial, we'll just need a basic limb. How about a leg?

Blender ss

Thank you, volunteer. Now that we've ripped her leg from the rest of her body, we can just work with the leg. Trust me, once you just get boning a limb down, you'll be able to apply that method to boning a whole body.

NOTE: I'm doing this with Blender 2.46, the one with the Big Buck Bunny splash screen. I must say up front as a disclaimer that if you even think of attempting this tutorial with any other version of Blender, before or since, you will lose your mind. Permanently. This tutorial is only for version 2.46. Since every version changes something and makes every previously-written tutorial useless, we have no choice but to specify each and every version down to the last possible snap-shot instant day, hour, and minute. So. Version 2.46, downloaded and installed on May 18th, 2008, at 2:02 PM, Central Standard Time.

I can't answer any questions about Blender. I'm channeling this tutorial through Tarot cards.

So select the leg.

Click the cursor (the little annoying red-and-white life preserver thingie) to the thigh end of the leg. You might want to view the leg from top and side to ensure the cursor is centered.

Blender ss

Hit the space bar to get the menu. Select Add... armature.

Blender ss

Hit 'tab' to go into edit mode. Hit 'z' to go to wireframe mode. Hit your head to go into migraine mode, but only after we're done. You should have this:

Blender ss

Now hit 'g' for 'grab' mode and drag that end of the bone with the mouse until it's inside the knee.

Blender ss

Now, you know how you hit the 'e' key to extrude a section of mesh? It works the same way with bones. So when we're at the knee, just hit 'e' and keep on draggin' until you're in the ankle. Click to set it.

Blender ss

Now one problem: When we hit 'z' to turn off wire-frame mode and see how it looks, we can't see the bone (well, not all of it) because it's inside the leg. So in the little bottom panel labeled 'armature', click 'x-ray' and 'auto 1k' while you're at it. 'x-ray' will allow the bone to be visible in edit mode, and 'auto ik' will make it behave more leg-bone-like when we move it. Also hit 'names' so it will show the bone's names.

Blender ss

So then hit 'z' and behold:

Blender ss

Now hit 'tab' to go back to object mode. And right-click on the leg - not the bone - to select the leg - not the bone. Then hit 'tab' for edit mode and hit 'a' to select all of the mesh.

Blender ss

Here is what we have to do next: Tell Blender that this leg has to be attached to the bones. To do that, we have to identify the leg and the bones, and explicitly tell each one how it relates to the other. Because computers are stupid.

So under the bottom section called 'link and materials', under 'vertex groups', hit 'new'. A little box pops up; your group of vertexes is named 'group'. Let's keep it at least this real by clicking in the word 'group' and deleting it, typing in the word 'leg' instead and hitting 'enter'. Then click 'assign'. Now all of the vertexes belong to the 'leg' group.

Blender ss

Hit 'tab' to go back to object mode. Now look down at the little boxes at the bottom again, and a new box appeared named 'Modifiers'. Click the 'add modifier' button and select 'armature' from the menu, and you have a new little box. Under 'Ob:', type 'Armature' (yes, of course, it's case sensitive!) since that's the name Blender automatically assigned it this time, and under 'VGroup', type 'leg' for what we named the hunk of meat we're trying to control.

Blender ss

Now, you're in 'object' mode, the leg is selected, and you're this far. Now hold the shift key and right-click the bones. Now the leg 'n' bones are selected. Now hit Ctrl-P (the 'parent' operation), select 'armature', and in the second menu select 'name groups'.

Blender ss

Ah! Whoo! You're done! You've finally gotten a bone inside a body part and taught it to move together! To review the fruit of your labors, use the little mode selector menu...

Blender ss

And then right-click on a bone to select it and hit 'g' to grab it and move that sucker around. Wow!

Blender ss

OK, can anybody see where something went wrong? Most of the leg's moving, but the toes are stuck in space and the rest of the vertices stay attached but stretchy like we stepped in some chewing gum. Oh, God! We didn't add a foot bone! We should have done that. Then the whole thing would move with us. So I did this to illustrate a 'gotcha': be sure that the meat all has sufficient bones in it. In real modeling, you would have not only extended a foot bone, but probably bones for each individual toe, right?

Here's a knight I did a while back for a project which didn't pan out. Just to show that, yes, it can be done right.

Blender ss

Blender ss

Note the bone structure I've high-lighted inside the foot. The way bones behave, the smaller they are, the less skin area they possess with this method. Since an armored knight is a walking tin can and isn't animated down to individual toes anyway, it doesn't matter that we aren't replicating the whole bone structure here. Just enough to make the whole foot come along with the bones.

Hope you got something out of this. For that matter, I hope I can follow it the next time I have to bone something. For further knowledge, I recommend the education and help section of the Blender site, and I also recommend you buy a copy of the Blender Book.

There's no way I'm qualified to do this tutorial, but I searched all over the web and found nothing for this. So now one exists. It will be out of date in five minutes when they release the next version of Blender and play Twister with the interface again, after which time I will be punished for all eternity by angry readers trying to follow this tutorial with version 2.47++ and screaming "I tried to follow this and it's wrong! You suck!"

C'est la vie. (corrected per Perlejade's comment)

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Image Magick Banner Generator - part 5

Date/Time Permalink: 03/25/08 01:17:45 am
Category: Graphics Tutorials

So here we are all at the end of the Image Magick banner generation project. So I was twiddling about typing different little strings into "random_banner.sh" and displaying the results. And then I had the idea to write this script:

"make_banners.sh"

#!/bin/bash

  for NUM in $(seq 1 100);
  do
    WORD1=$(./random_line.sh /usr/share/dict/words)
    WORD2=$(./random_line.sh /usr/share/dict/words)
    NEWFILE=$WORD1"_"$WORD2".png"
    ./random_banner.sh "$WORD1 $WORD2"
    mv Banner.png ./banner_gallery/$NEWFILE
  done

exit 0

What it does is pick two random words from /usr/share/dict/words and pop them through the banner generator, then save them in a subfolder. 100 at a time. Then I can browse through the folder later and cherry-pick anything interesting.

The result is a toy that's half word-play and half image-play. Most of the results either have no meaning or aren't very pretty, but some of them are very interesting.

Some are just crying out to have blogs written under them:

corollary_gather
diminishing_journalist
dreamily_cogitated
juggling_blasphemies
mirth_artifact
needing_guiltily

...perhaps "Needing Guiltily" is already being used for some passionate, torid, bodice-ripper journal somewhere...

poet_dispassionate
sanitarium_sentences

Others sound like they're a good business idea:

censored_fashions

...if you saw a lingerie store called "Censored Fashions", you'd want to browse around, wouldn't you?

serendipity_throughput

...there's a hip, Faith Popcorn-type business waiting to be founded with the name "Serendipity Throughput". I can just feel it.

Other results are just cool for no specific reason:

apt_honeybee
hang_birdie
imp_found

There's that imp! I've been looking all over for it!

mead_aura

A "mead aura" is the alcoholic glow you get from drinking too much mead.

piddle_mushy

There, I've invented my own word! "Piddlemushy" means semi-liquid soft. Used in a sentence: "This cake didn't bake long enough - the middle of it is still piddlemushy!" Somebody with an Urban Dictionary account want to make it official?

speeding_doper

...but at least it's not a doping speeder.

Then again, some of these sound like the product of a dirty mind...

girlish_albumin

Ewwwww!

sexuality_sapling
uniform_stickiness
piss_guru

That's one of those phrases that doesn't leave your mind for a while. I just hope there's no such thing...

Anyway, I'd better be
gloriously_striding
along.

So, to wrap up: The usefulness of toys like these, besides dadaist entertainment, is to act as a catalyst for ideas. If you feel a creativity slump, you can run off a dozen of these and surf them, sampling each concept as the system pitches phrases at you that you never thought of before, and draws them in sometimes compelling ways that add an extra shade of meaning.

But really, I hope I've demonstrated some of the capacity of the fantastic Image Magick. It really is a misunderstood program, as most people don't know the tenth of what it can do.

Yet another another lazy banner

The whole Image Magick Banner Generator project:

part 1 - get a random line from a file, applying bevels and borders to an image.
part 2 - generate a solid or gradient background.
part 3 - generate a pattern or plasma noise background.
part 4 - generate the text itself, and use all of the previous scripts to make a banner.
part 5 - a final wrapper script, and some funny results.
Project Tarball with all scripts, GPL'ed

Useful Image Magick links:

Image Magick home page manual
Examples of ImageMagick Usage - a fantastic suite of tutorials!
Fred's Image Magick scripts

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Image Magick Banner Generator - part 4

Date/Time Permalink: 03/22/08 11:30:04 am
Category: Graphics Tutorials

OK, the day we've been waiting for: the thing that's going to actually make text banners out of all these parts!

Here it be, saved as "random_banner.sh":

#!/bin/bash

if [ "$1" ]; then
  TEXT="$1"
else
  echo "USAGE random_banner.sh TEXT"
  exit 1
fi

# A basic text banner
  echo "$TEXT" > temp_text
  ls /usr/X11R6/lib/X11/fonts/TTF/*.ttf > temp_font_list
  FONT=$(./random_line.sh temp_font_list)
  rm temp_font_list
  FGCOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')

  CONVERTSTRING=" -background none"
  CONVERTSTRING="$CONVERTSTRING"" -fill ""$FGCOLOR"
  if [ "$(($RANDOM % 2))" = 1 ]; then
    STROKECOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
    CONVERTSTRING="$CONVERTSTRING"" -strokewidth 1"
    CONVERTSTRING="$CONVERTSTRING"" -stroke ""$STROKECOLOR"
  fi

  CONVERTSTRING="$CONVERTSTRING"" -font ""$FONT"
  CONVERTSTRING="$CONVERTSTRING"" -pointsize ""$(($RANDOM % 40 + 30))"
  CONVERTSTRING="$CONVERTSTRING"" label:@temp_text"
  CONVERTSTRING="$CONVERTSTRING"" -gravity center Banner.png"

#  echo $CONVERTSTRING
  convert $CONVERTSTRING
  rm temp_text

# Some special effects for the text?
# Like, say, a wave?
  if [ "$(($RANDOM % 8))" = 1 ]; then
    WAVESTRING="Banner.png -matte -background none -wave "
    WAVESTRING="$WAVESTRING""$(($RANDOM % 5 + 3))"x"$(($RANDOM % 200 + 200))"" Banner.png"
    convert $WAVESTRING
  fi
# Perhaps some shade?
  if [ "$(($RANDOM % 2))" = 1 ]; then
# Maybe with a blur?
    if [ "$(($RANDOM % 2))" = 1 ]; then
      BLURSTRING="Banner.png -blur 0x""$(($RANDOM % 4 + 3))"" Banner.png"
      convert $BLURSTRING
    fi
    SHADESTRING="Banner.png -shade ""$(($RANDOM % 180 + 0))""x""$(($RANDOM % 40 + 5))"" Banner.png"
    convert $SHADESTRING
# Since we shaded it, it's gray now, so tint it back.
    TINTSTRING="Banner.png -fill ""$FGCOLOR"" -tint ""$(($RANDOM % 80 + 60)) Banner.png"
    convert $TINTSTRING
  fi


# Get the size of the text banner, then pad it a little
  IMGSIZE=$(identify Banner.png | awk '{print $3}')
  IMGX=$(echo $IMGSIZE | awk -Fx '{print $1}')
  IMGY=$(echo $IMGSIZE | awk -Fx '{print $2}')
  IMGX=$(($IMGX + $(($IMGX / 10))))
  IMGY=$(($IMGY + $(($IMGY / 30))))
  IMGSIZE=$IMGX"x"$IMGY

# Make a background to fit the banner
  case $(($RANDOM % 4 +1)) in
    1)
      ./generate_background_solid.sh $IMGSIZE
      ;;
    2)
      ./generate_background_gradient.sh $IMGSIZE
      ;;
    3)
      ./generate_background_pattern.sh $IMGSIZE
      ;;
    4)
      ./generate_background_noise.sh $IMGSIZE
      ;;
  esac

  composite -gravity center Banner.png background.png Banner.png
  rm background.png

# Chance of bevel or frame
  if [ "$(($RANDOM % 2))" = 1 ]; then
    ./bevel.sh Banner.png
  fi
  if [ "$(($RANDOM % 2))" = 1 ]; then
    ./frame.sh Banner.png
  fi

exit 0

It's a doozy! Here's a section-by-section breakdown:

  • All it needs to start is the text string, which you must quote. Example: ./random_banner.sh "your text here"
  • Next it uses the random line script to pick out a random font from your X11's font library. Because I have free fonts running out my ears, I get a lot of variety. If you don't have many fonts, you won't get much. You won't get anything but an error if /usr/X11R6/lib/X11/fonts/TTF/ is empty. Will this work with other kinds of fonts? I dunno yet.
  • Anyway, it pumps your text string using that font into a backless banner, sized automatically to suit the text.
  • Then it rolls the dice to see about applying special effects, being waves, blurring or shading.
  • Now it has the text banner saved, so it has to use the 'identify' command to find out how big the banner is, then size it a bit larger.
  • Then based on those specs, it picks one of the background-generating scripts we've been yammering about the past few days.
  • It generates the background and slaps the text on top of it with the 'composite' command, and rolls the dice one last time to see about applying a frame or bevel or both.

Ding! It's done! Now, some bugs and problems:

First, there's no control for making sure you can read it. It might pick pink text on a pink-to-purple gradient background. The best practice is to run it a few times, saving over the old banner, until you get a nice one.

Second, a big issue, is that the top and bottoms of fonts tend to get clipped. This only happens with improperly made fonts, which don't have good information on where the boundaries lie for individual letters. This is what happens when you download a lot of free fonts over the Internet. People just grab an old file, paste their letter shapes in over the old ones, save it and upload it. "Kerning" is not in their vocabulary. See a discussion of this here.

Last, you're going to get some banners that are just ghastly. Just try again. I've put as many controls as I can in here to reduce the "dud rate", but after all we're asking it to randomly create banners with as much creative freedom as possible. It's meant as an amusing toy and a way to show some of IM's more sophisticated capabilities, not a full-fledged enterprise software.

For instance, I just typed

./random_banner.sh "Image Magick rocks"

and got 'Banner.png'...

Image Magick rocks

...but who knows what you'll get next time?

IMBG.tar.gz

And at last, ▲ here's the promised tarball of all the scripts in one handy directory called "IMBG" (Image Magick Banner Generator), complete with GPL license! Yes, world, it is yours! Run away, little program, go free! However, it could stand to be more robust if anybody's going to take it seriously.

Also included in the tarball is a small script that generates 100 banners with two randomly picked words each and saves them in a subdirectory called "banner_gallery". We'll explore that little appendix to the project and the fascinating results next time.

Still another random sig

The whole Image Magick Banner Generator project:

part 1 - get a random line from a file, applying bevels and borders to an image.
part 2 - generate a solid or gradient background.
part 3 - generate a pattern or plasma noise background.
part 4 - generate the text itself, and use all of the previous scripts to make a banner.
part 5 - a final wrapper script, and some funny results.
Project Tarball with all scripts, GPL'ed

Useful Image Magick links:

Image Magick home page manual
Examples of ImageMagick Usage - a fantastic suite of tutorials!
Fred's Image Magick scripts

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Image Magick Banner Generator - part 3

Date/Time Permalink: 03/20/08 10:39:56 am
Category: Graphics Tutorials

In part 2, we learned how to generate solid backgrounds and gradients. In this part, I'll show you how to generate patterned and random noise backgrounds. First, the patterns, which are more basic:

Save it as "generate_background_pattern.sh"

#!/bin/bash

if [ "$1" ]; then
  SIZE="$1"
else
  echo "USAGE generate_background_pattern.sh SIZE (XxY)"
  exit 1
fi

  PATTERNS=( bricks checkerboard circles crosshatch crosshatch30 crosshatch45 fishscales \
            gray5 gray20 gray55 gray95 hexagons horizontal horizontalsaw hs_bdiagonal \
            hs_cross hs_diagcross hs_fdiagonal hs_horizontal hs_vertical left30 \
            left45 leftshingle octagons right30 right45 rightshingle smallfishscales \
            vertical verticalbricks verticalleftshingle verticalrightshingle verticalsaw )
  PATTERN=${PATTERNS[$(($RANDOM % 32))]}

  CONVERTSTRING=" -size ""$SIZE"
  CONVERTSTRING="$CONVERTSTRING"" pattern:""$PATTERN -normalize"
  CONVERTSTRING="$CONVERTSTRING"" -shade "$(($RANDOM % 150 +50))"x"$(($RANDOM % 60 +10))
  CONVERTSTRING="$CONVERTSTRING"" background.png"

  convert $CONVERTSTRING

exit 0

All of the patterns in the $PATTERNS array come built-in with Image Magick. So our task is simply to list them, and pick a random one. A step I elected not to make optional is to use the 'shade' argument as well, which is similar to bumpmapping and make the pattern stand out better.

Some sample patterns produced with a
"./generate_background_pattern.sh 400x100":

pattern background example

pattern background example

pattern background example

Pretty elementary...

The random noise one, on the other hand, is much busier:

"generate_background_noise.sh"

#!/bin/bash

if [ "$1" ]; then
  SIZE="$1"
else
  echo "USAGE generate_background_gradient.sh SIZE (XxY)"
  exit 1
fi

  CONVERTSTRING=" -size ""$SIZE "
  case $(($RANDOM % 6 +1)) in
    1) CONVERTSTRING="$CONVERTSTRING""plasma: -fill grey -colorize 75% " ;;
    2)
      FROMCOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
      TOCOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
      CONVERTSTRING="$CONVERTSTRING""plasma:""$FROMCOLOR""-""$TOCOLOR ""-fill gray -colorize 75% "
      ;;
    3) CONVERTSTRING="$CONVERTSTRING""plasma:""grey-grey -blur 0x5 " ;;
    4) CONVERTSTRING="$CONVERTSTRING""plasma:""white-white " ;;
    5) CONVERTSTRING="$CONVERTSTRING""plasma:""black-black ""-fill black -colorize 75% " ;;
    6) CONVERTSTRING="$CONVERTSTRING""xc: -fx rand() -blur 0x2 " ;;
  esac
  if [ "$(($RANDOM % 6))" = 1 ]; then
    CONVERTSTRING="$CONVERTSTRING""-blur 0x2 -emboss .2 "
  fi
  if [ "$(($RANDOM % 6))" = 1 ]; then
    CONVERTSTRING="$CONVERTSTRING""-charcoal 3 -negate "
  fi
  if [ "$(($RANDOM % 6))" = 1 ]; then
    CONVERTSTRING="$CONVERTSTRING""-edge 1 "
  fi
  case $(($RANDOM % 5 +1)) in
    1) CONVERTSTRING="$CONVERTSTRING""-fx intensity " ;;
    2) CONVERTSTRING="$CONVERTSTRING""-blur 0x""$(($RANDOM % 3 + 1)) " ;;
    3) CONVERTSTRING="$CONVERTSTRING""-colorspace gray " ;;
    4) CONVERTSTRING="$CONVERTSTRING""-shade ""$(($RANDOM % 180 + 0))""x""$(($RANDOM % 10 + 5)) " ;;
    5) CONVERTSTRING="$CONVERTSTRING " ;;
  esac

  CONVERTSTRING="$CONVERTSTRING""background.png"
  convert $CONVERTSTRING

exit 0

Oooga! See, the noise generators that come built-in with Image Magick often produce patterns that are far too strong to read any text in front of them. So we have to soften them with filters like 'blur', 'edge', and 'charcoal'. But some of them are better without. Finally, the built-in plasma generator produces radically different results depending on what color arguments you give it:

white-white:
white plasma

black-black:
black plasma

...or even giving it no arguments at all. So it's better to treat these various "colors" of plasma as their own separate noise generators, to say nothing of the "xc: -fx rand()" method, which gives a similar pixel-static every time:

static noise

By the way, the '-fx' argument cloaks a vast new unexplored territory, being a built-in mini-language of math formulas applied to RGB color space. I'm still figuring that one out.

In a nutshell, you want some variety, but you want to keep the chaos controlled just enough so it doesn't spoil too many banners.

Anyway, here's a few examples produced by this module with
"./generate_background_noise.sh 400x100":

noise background example

noise background example

noise background example

noise background example

As you can see, you can get anything from a stucco texture to a marble look, and much more.

That takes care of all the backgrounds. The only thing left is to generate some text, slap it on a background, and Bonnie's your aunt! We'll get to the big beast of a script that does that next time.

yet another random sig

The whole Image Magick Banner Generator project:

part 1 - get a random line from a file, applying bevels and borders to an image.
part 2 - generate a solid or gradient background.
part 3 - generate a pattern or plasma noise background.
part 4 - generate the text itself, and use all of the previous scripts to make a banner.
part 5 - a final wrapper script, and some funny results.
Project Tarball with all scripts, GPL'ed

Useful Image Magick links:

Image Magick home page manual
Examples of ImageMagick Usage - a fantastic suite of tutorials!
Fred's Image Magick scripts

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Image Magick Banner Generator - part 2

Date/Time Permalink: 03/18/08 01:18:43 pm
Category: Graphics Tutorials

Today's pieces of the banner generator puzzle are a couple of scripts to generate backgrounds. We'll start with the most basic one.

I have this script saved as "generate_background_solid.sh":

#!/bin/bash

if [ "$1" ]; then
  SIZE="$1"
else
  echo "USAGE generate_background_solid.sh SIZE (XxY)"
  exit 1
fi

  BGCOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
  convert -size $SIZE xc:"$BGCOLOR" background.png

exit 0

...almost self-explanatory. Given an XxY argument, it produces a random solid-color background. "./generate_background_solid.sh 400x100" gets you something like this:

solid background example

Later on in the project, we'll see how we use Image Magick's 'identify' command to get the size of a banner made with text, so we know how to pass that size argument to the background scripts. Right now, let's deal with a thornier problem, generating a gradient and not having it just be straight up and down.

I have this script saved as "generate_background_gradient.sh":

#!/bin/bash

if [ "$1" ]; then
  SIZE="$1"
else
  echo "USAGE generate_background_gradient.sh SIZE (XxY)"
  exit 1
fi

  FROMCOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
  TOCOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
  STARTSIZE=$(($(echo $SIZE | awk -Fx '{print $1}')+10))
  STARTSIZE=$STARTSIZE"x"$STARTSIZE

  CONVERTSTRING=" -size ""$STARTSIZE"
  CONVERTSTRING="$CONVERTSTRING"" gradient:""$FROMCOLOR-$TOCOLOR"
  CONVERTSTRING="$CONVERTSTRING"" -rotate ""$(($RANDOM % 360 + 1))"
  CONVERTSTRING="$CONVERTSTRING"" -gravity center -crop ""$SIZE""+0+0"
  CONVERTSTRING="$CONVERTSTRING"" background.png"

  convert $CONVERTSTRING

exit 0

...not nearly as straight-forward as we had hoped. See, first we pick two random colors, then we have to get the 'X' width (the longest dimension) and pad it some, then crop it back down to our expected size. Let's show why we have to do it this way:

If we run:

convert -size 400x100 gradient:red-blue background.png

we get this:

straight background

If we want a gradient that goes some other orientation besides straight up and down, we can simply add the '-rotate' option, right?

convert -size 200x50 gradient:red-blue -rotate 45 background.png

But I see a problem:

caddywumpus background

and cropping it down to the original size doesn't help:

convert -size 200x50 gradient:red-blue -rotate 45 -gravity center -crop 200x50+0+0 background.png

wrong background

...so what we have to do is generate the gradient at a much larger size, say a square with its size as the widest dimension of the desired banner. How's that working for us?

convert -size 200x200 gradient:red-blue -rotate 75 -gravity center -crop 200x50+0+0 background.png

clipped background

We almost got away with that! But look closely and you'll see, for this rotation of 75 degrees, we ended up with a corner chipped out of the upper-right and lower-left.

Sooooo, we have to add an extra ten pixels on the border of the square, which we can then crop down to the proper size for a banner background. And that explains all the calisthenics in the script... hopefully.

Running it gives backgrounds like these:

correct gradient background

correct gradient background

correct gradient background

correct gradient background

How trendy! We'll explore patterned backgrounds next.

a random banner sig

The whole Image Magick Banner Generator project:

part 1 - get a random line from a file, applying bevels and borders to an image.
part 2 - generate a solid or gradient background.
part 3 - generate a pattern or plasma noise background.
part 4 - generate the text itself, and use all of the previous scripts to make a banner.
part 5 - a final wrapper script, and some funny results.
Project Tarball with all scripts, GPL'ed

Useful Image Magick links:

Image Magick home page manual
Examples of ImageMagick Usage - a fantastic suite of tutorials!
Fred's Image Magick scripts

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

Image Magick Banner Generator - part 1

Date/Time Permalink: 03/17/08 09:08:34 am
Category: Graphics Tutorials

I'm going to try an experiment: blogging a whole project for a little graphics toy I've managed to hack out. You are welcome to copy and save scripts as we go along, just read them and learn how to do it yourself, modify them to your own purposes, or just nod your head and go "Uh-huh, gawrsh, lookit the purty code boxes!" as they fly by.

This will be a multi-part posting of a project. It's just a group of scripts which, when assembled together, make an interesting toy, and also teaches some practical use of the fantastic, but mysterious (to many), Image Magick tool suite.

If you don't want to collect the parts day by day, wait to the end when I'll wrap the whole project up in a tarball for downloading.

The first piece is a script version of a command I shared a couple days ago in Obscure Linux Commands: Some of My Favorite Incantations:

#!/bin/bash

if [ "$1" ]; then

  WORDLINE=$((($RANDOM * $RANDOM) % $(wc -l $1 | awk '{print $1}') + 1))"p"
  sed -n $WORDLINE $1

else
  echo "USAGE: random_line.sh $FILE"
fi

exit 0

Save it as "random_line.sh" if you're following along with this project. What it does is cough up a random line from any text file, and we'll be using it to select random colors from rgb.txt, random fonts from the X11 font directories, and all kinds of other abuse.

If you visit that post in the above link, be sure to check out the comments section for Michael Johnson, who posts an even more elegant construction for getting a random line from a file. As they say in the Perl community, "My apologies for the needlessly verbose script"! You can use his method or mine, no difference.

NOTE: In spite of the Unix words list being so standard that it's written up Wikipedia, not all Linux distros have it under the same name and in the same place. So check that Wikipedia article for other clues to tracking it down on your system.

Now for the second piece:

#!/bin/bash

  BEVELWIDTH=$(($RANDOM % 10 + 3))
  BEVELWIDTH=$BEVELWIDTH"x"$BEVELWIDTH

  if [ "$(($RANDOM % 2))" = 1 ]; then
    convert $1 -raise $BEVELWIDTH $1
  else
    convert $1 +raise $BEVELWIDTH $1
  fi

exit 0

Save it as "bevel.sh" if you're following with this project. All it does is add a random bevel to a given image. Given the following image saved as "solid_background_1.png":

solid_background_1.png

running "./bevel.sh solid_background_1.png" might produce this:

beveled_background_1.png

In ImageMagick's 'convert' command, "-raise" will produce a raised bevel and "+raise" will produce a sunken bevel.

And here's one more piece:

#!/bin/bash

  FRAMECOLOR=$(./random_line.sh /usr/X11R6/lib/X11/rgb.txt | cut -f 3- | sed 's/[ \t]*//g')
  BEVELWIDTH1=$(($RANDOM % 10))
  BEVELWIDTH2=$(($RANDOM % 10))
  
  CONVERTSTRING="$1 -mattecolor ""$FRAMECOLOR"
  CONVERTSTRING="$CONVERTSTRING"" -frame "$(($RANDOM % 15 + $BEVELWIDTH1 + $BEVELWIDTH2))
  CONVERTSTRING="$CONVERTSTRING""x"$(($RANDOM % 15 + $BEVELWIDTH1 + $BEVELWIDTH2))
  CONVERTSTRING="$CONVERTSTRING""+"$BEVELWIDTH1"+"$BEVELWIDTH2" "$1

  convert $CONVERTSTRING

exit 0

which you can save as "frame.sh" if you're following along. All it does is generate a random frame, which is actually kind of a double-bevel, except that it also makes the frame a random color.

Given the following image saved as "solid_background_1.png":

solid_background_1.png

running "./frame.sh solid_background_1.png" might give you this:

framed_background_1.png

You can see already we're calling "random_line.sh" to get a random color from X11's "rgb.txt" file. We also have some bizarre incantations which need explaining:

First off, the formatting on rgb.txt is a little weird. It has spaces in some color names, it uses tabs, and generally makes itself a pain to process through a script. An alternative way to get a color list is to run this command:

convert -list color

...and save the output into a file, which you can then pick a random line from.

Also, the numbers that you feed to the convert command's "-frame" switch requires that the frame width be equal to or greater than the width of the inside and outside bevels, or it will produce an error. So we have to figure that into the formula for the argument to "-frame".

Here's a tutorial on ImageMagick framing which explains it better.

OK, so far we have "random_line.sh", "bevel.sh", and "frame.sh", the first three parts of our project "Image Magick Banner Generator" (IMBG). You'll probably want to save these in their own folder, because this project will have nine scripts total by the time we're done. I also break it down into smaller scripts, because the individual parts are useful on their own outside this context.

*Whew!* God, I hope I'm getting this right!

a random banner sig

The whole Image Magick Banner Generator project:

part 1 - get a random line from a file, applying bevels and borders to an image.
part 2 - generate a solid or gradient background.
part 3 - generate a pattern or plasma noise background.
part 4 - generate the text itself, and use all of the previous scripts to make a banner.
part 5 - a final wrapper script, and some funny results.
Project Tarball with all scripts, GPL'ed

Useful Image Magick links:

Image Magick home page manual
Examples of ImageMagick Usage - a fantastic suite of tutorials!
Fred's Image Magick scripts

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

<< Previous Page :: Next Page >>
suddenly the moon