Click here to Skip to main content
Click here to Skip to main content

GPaint

, 7 Jun 2004
Rate this:
Please Sign up or sign in to vote.
GPaint: is a program to create Google-like logos.

Introduction

GPaint is a program to create Google-like logos. It is a command line program which takes as input a font name, a font size, the text, a "color cycling scheme", and a file name. The font of the Google logo is Catull, but Catull is a commercial font, so chances are you don't have it on your computer. Don't worry though, Book Antiqua looks a lot like Catull and, don't forget, you can use any font you like. When GPaint is invoked like this:

C:\>gpaint "book antiqua" 80 "Google" "2159d6;e73c21;efba00;2159d6;31b639" logo

You will get this .bmp file as a result (converted to jpeg):

OK, I admit, it is not exactly like the Google logo, but it's nice, isn't it?

GPaint will change the color for each character in the string. For example, suppose the color cycling scheme is "ff0000,0000ff", then GPaint will paint the first character in red, the second in blue, the third again in red etc.

GPaint Internals

GPaint uses the following classes: FastBitmap, Layer, Layers, LayeredImage and GPaint.

FastBitmap is a class which contains a Bitmap. It is called FastBitmap because it provides methods to access the bits of the Bitmap member without using the very slow GetPixel() and SetPixel() methods of the Bitmap class. The code has to be compiled with the /unsafe option because the GetPixel() and SetPixel() methods of FastBitmap use pointers.

LayeredImage represents an image which consists of 1 or more layers. Programs like Photoshop and GIMP use a stack of layers to create attractive images. GPaint contains a small "Image Composition Engine" like the ones found in those programs - a very small one.

Layers represents the layer stack. It has methods to add and copy a layer.

Layer represents, well, a layer.

Let's see how GPaint uses these classes to generate a logo. Here's some code which you can find in the Main() method of the GPaint class:

...

// create image

LayeredImage image = new LayeredImage(totalwidth + 4, 
                tm.tmHeight + 4 + 4);

First, we create a new LayeredImage. Totalwidth is the width of the string and tm.tmHeight the height of the string in the given font. The width and height is increased by 4 because of the drop shadow. We add another 4 pixels to the height to make sure the drop shadow is completely visible, but this value is arbitrary. Now that we have an image, we can continue to add some layers.

Layer bg = image.Layers.Add();
bg.Clear(Color.Black);
bg.DrawText(0, 0, s, font, new SolidBrush(Color.White));

The layer bg contains the text in white on a black background. We will use this layer as a mask.

Layer copybg = image.Layers.Copy(bg);
copybg.Blur(4, 4);

copybg is a copy of the bg layer. We blur it 4 pixels horizontally and 4 vertically. This layer will be used as a bump map, and an inverted copy of this layer will serve as the drop shadow.

Layer white = image.Layers.Add();
white.Clear(Color.White);

The layer white is simply the background.

Layer shadow = image.Layers.Copy(copybg);
shadow.Invert();
shadow.Opacity = 0.5;
shadow.OffsetX += 4;
shadow.OffsetY += 4;

Layer shadow contains the drop shadow. We copy the bump map, invert its colors, set the opacity to 0.5 to make it less dark, and move it a bit.

Int32 offsetx = 0;
Int32 colorindex = 0;
Layer final = image.Layers.Add();
for (Int32 i = 0; i < s.Length; i++) {
    Color c = colors[colorindex];
    colorindex++;
    if (colorindex >= colors.Length)
        colorindex = 0;
    SolidBrush brush = new SolidBrush(c);
    final.FillRectangle(offsetx, 0, widths[i], tm.tmHeight, brush);
    offsetx += widths[i];
}

final is the layer we will bump map. colors is the color cycling scheme and widths contains the width of each character in the string. A rectangle is painted "above" each character in the right color.

final.BumpMap(copybg, 135, 45, 3, false);

Now that we have a "flag-like" bitmap, we can bump map it with azimuth 135, elevation 45 and depth 3.

// very important -- Clone() bitmap, otherwise Lock()
// will be called twice!!
final.Mask = (FastBitmap)bg.Bitmap.Clone();

As said in the beginning, bg will be used as a mask. As a result, only the bump mapped text will be visible on this layer and the white background and drop shadow will show through.

FastBitmap result = image.Flatten();
result.Save(args[4] + ".bmp", ImageFormat.Bmp);

And finally, ladies and gentlemen, we flatten the image and write it to disk.

Some Thoughts

  • Maybe a better name would be GString?
  • I should organize the code a bit better. Putting filters in the layer class is not a good idea, but it's not my intention to write a complete image manipulation library.
  • Because I DllImport() GetCharWidth() to get the width of a character, I don't think GPaint runs on Mono.
  • If someone can try this program with font Catull, please tell me where I can see a picture.

Exercise

Write a program which adds drop shadows to pictures automatically.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mike Finnegan

Belgium Belgium
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pinmembermanoj kumar choubey26-Feb-12 21:20 
Generalsting is a bit old, but what the hay Pinmembercwixom30-Dec-07 8:57 
QuestionIts very nice program. Can we create using gimp ? Pinmembermsrinirao29-Nov-06 18:22 
AnswerRe: Its very nice program. Can we create using gimp ? Pinmemberq12345678929-Nov-06 22:46 
GeneralYour site pictures PinmemberSaied Javadi11-Jul-06 3:03 
GeneralRe: Your site pictures Pinmemberq12345678911-Jul-06 23:39 
GeneralRe: Your site pictures [modified] PinmemberSaied Javadi12-Jul-06 4:12 
GeneralNice Program, but Photoshop Works too PinsussAnonymous22-May-05 8:05 
GeneralRe: Nice Program, but Photoshop Works too PinsussAnonymous22-May-05 22:01 
GeneralRe: Nice Program, but Photoshop Works too PinsussAnonymous11-Jun-05 17:50 
First, I used Photoshop. Then I inserted text, and changed the font size and colors. Then I just added bevel and shadow! It's really easy with photoshop.
GeneralHere it is in the actual Catull font Pinmemberintelliot21-Feb-05 9:27 
GeneralRe: Here it is in the actual Catull font Pinsussprogramvolcomkid18-Apr-05 15:58 
GeneralRe: Here it is in the actual Catull font Pinmemberintelliot18-Apr-05 18:39 
GeneralNice work Pinmembermbeatini4-Nov-04 2:58 
GeneralGood example PinmemberBill Seddon23-Sep-04 4:41 
GeneralRe: Good example PinsussAnonymous25-Sep-04 4:46 
GeneralAntiAlias improvement PinmemberACoolDude17-Jun-04 23:28 
GeneralNice code PinmemberWillemM8-Jun-04 20:19 
Generaldll file missing too PinsussHorace38018-Jun-04 5:26 
GeneralRe: dll file missing too PinmemberColin Angus Mackay8-Jun-04 10:51 
GeneralRe: dll file missing too PinmemberLeslie Sanford8-Jun-04 16:37 
GeneralRe: dll file missing too PinsussHorace38018-Jun-04 16:59 
GeneralRe: dll file missing too PinmemberLeslie Sanford8-Jun-04 17:11 
GeneralRansom Pinmembergarythom_usa8-Jun-04 4:08 
GeneralRe: Ransom Pinmemberpeterchen8-Jun-04 10:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.141022.2 | Last Updated 8 Jun 2004
Article Copyright 2004 by Mike Finnegan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid