Take the 2-minute tour ×
Graphic Design Stack Exchange is a question and answer site for Graphic Design professionals, students, and enthusiasts. It's 100% free, no registration required.

I'm trying to create a "set" of buttons. Actually I can make the buttons somewhat easily.

In GIMP I have a template (It's a rectangle… soooo complicated).

  • Take template, add text to text box for button one and save it.
  • Change text color for button one, save it. (Different colors for mouse-over).
  • Take template, add different text for button two and save it
  • … (You can see where this goes)
  • Change text color for button TWENTY… ugh…

So, what I'm trying to figure out is: how I can create multiple JPEGs at the same time? Bulk creation. Given a template (of which I can change the font, size, color, etc), I could click "create" and bam I have 40 images.

Example buttons below. Each button is a jpeg in two pairs: white Lettering, yellow for mouseover.

Buttons

share|improve this question
4  
Is this for a web site? if so, post a sample...you might be better off doing this with CSS rather than creating a unique image for every button. –  DA01 Sep 9 '11 at 21:08
    
As far as little googling tells me, Gimp does have some sort of slicing much like photoshop does docs.gimp.org/en/python-fu-slice.html –  Joonas Sep 10 '11 at 12:50
2  
Those are really simple buttons and would be incredibly easy to generate in HTML and CSS alone--no need for images at all (which should save you time and your users download speeds). Let me know if you'd like help with that. –  DA01 Sep 10 '11 at 18:39
    
@DA01 Arguably true... That would require re-coding an ASP website made by someone else years ago. And hopefully it will be replaced in the future by a Drupal based site. Also, honestly, the button changes are infrequent enough that it's easier to just do it manually like I do atm. This is largely academic in nature. –  WernerCD Sep 11 '11 at 1:34
    
@Lollero I'll have to look into Slice... graphic editing is new enough to me that I don't know the terms to google more often than not. –  WernerCD Sep 11 '11 at 1:41
show 2 more comments

3 Answers 3

Below is a "basic" Script-Fu that takes two layer "subsets" and does the "cross-product" of them and exports a PNG for each combination. We have used this to create large numbers of such "button" images.

For example:

  1. Background-1
  2. Background-2
  3. Background-3
  4. Foreground-1
  5. Foreground-2

Factor 1 = "Background" and Factor 2 = "Foreground" Will create 6 exported PNGs.

Also note that you can have additional visible layers, e.g. drop shadow, and these will get copied through to each exported PNG. Just make sure you set the visibility of layers how you want and save before running the script.

This is as-is unsupported. If you don't know about Scheme or programming, you are probably better off doing the manual labor. If you are interested, or just love S-expressions, this script outputs some diagnostics and has some comments, so if you turn on the Script Console, you can see some output.

Copy the text below to "export-pngs.scm" and put that file into your GIMP "User" scripts folder, on Windows 7, "/Users/yourusername/.gimp-2.6/scripts". When you restart GIMP, there will be a new command File|Create|Create PNGs.

Please please please (that's 3) maintain attribution!

(define (script-fu-export-pngs filename outputfolder basename factor1 factor2)
    (let*
        (
        (image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
        (layerinfo (gimp-image-get-layers image))
        (layerarray (cadr layerinfo))
        (layers (vector->list layerarray))
        (layers-f1 (matching-layers layers factor1))
        (layers-f2 (matching-layers layers factor2))
        )
(gimp-message (string-append "layers-f1=" (layer-list layers-f1)))
(gimp-message (string-append "layers-f2=" (layer-list layers-f2)))

        (gimp-image-undo-disable image)
        (layers-visible (append layers-f1 layers-f2) FALSE)
        (for-each
            (lambda (layer-f1)
                (for-each
                    (lambda (layer-f2)
                        (let*
                            (
                            (output-filename (string-append outputfolder "/" basename "_"
                                (car (gimp-drawable-get-name layer-f1)) "_"
                                (car (gimp-drawable-get-name layer-f2)) ".png"
                            ))
                            )
                            (output-png image layers (list layer-f1 layer-f2) output-filename)
                        )
                    )
                    layers-f2
                )
            )
            layers-f1
        )
        (gimp-image-undo-enable image)
        (gimp-displays-flush)
    )
)
; set visibility of all layers in the list
; layers: layer list.
; vis: TRUE or FALSE.
(define (layers-visible layers vis)
    (for-each
        (lambda (layer)
            (gimp-drawable-set-visible layer vis)
        )
        layers
    )
)
; top-level save-as-PNG
; image: source image.
; layers: layer list.
; layer-factors: current-factors list.
; output-filename: full path to save.
(define (output-png image layers layer-factors output-filename)
    (let*
        (
        (width (car (gimp-image-width image)))
        (height (car (gimp-image-height image)))
        (type (car (gimp-image-base-type image)))
        (output (car (gimp-image-new width height type)))
        )
(gimp-message (string-append "output-filename=" output-filename "\noutput-image=" (layer-list layer-factors)))
        (gimp-image-undo-disable output)
        (output-image
            layers
            layer-factors
            (lambda (layer)
                (let*
                    (
                    (new-layer (car (gimp-layer-new-from-drawable layer output)))
                    )
;(gimp-message (string-append "add-layer " (car (gimp-drawable-get-name new-layer))))
                    (gimp-drawable-set-visible new-layer TRUE)
                    (gimp-image-add-layer output new-layer 0)
                    (gimp-image-lower-layer-to-bottom output new-layer)
                )
            )
        )
        (file-png-save2
            RUN-NONINTERACTIVE output
            (car (gimp-image-merge-visible-layers output CLIP-TO-IMAGE))
            output-filename output-filename
            FALSE 9 FALSE FALSE FALSE FALSE FALSE FALSE TRUE
        )
        (gimp-image-delete output)
    )
)
; traverse layers and call add-layer as necessary
; layers: layer list.
; layer-factors: current-factors list.
; add-layer: function to add selected layers.
(define (output-image layers layer-factors add-layer)
    (let*
        ()
        (for-each
            (lambda (layer)
                (let*
                    (
                    (layer-visible (car (gimp-drawable-get-visible layer)))
                    )
                    (cond
                        ((contains? layer layer-factors) (add-layer layer))
                        ((= layer-visible TRUE) (add-layer layer))
                    )
                )
            )
            layers
        )
    )
)
; scan layer list for layer-names starting with the prefix
; layers: layer list.
; prefix: starting prefix of layer name.
(define (matching-layers layers prefix)
    (let*
        (
        (output '())
        )
        (for-each
            (lambda (layer)
                (let*
                    (
                    (layer-name (car (gimp-drawable-get-name layer)))
                    )
                    (if (match-prefix? layer-name prefix) (set! output (append output (list layer))))
                )
            )
            layers
        )
        output
    )
)
; return #t/#f if target starts with the prefix
; target: target string to match.
; prefix: starting prefix.
(define (match-prefix? target prefix)
    (let*
        (
        (numchars (min (string-length prefix) (string-length target)))
        (pfx (substring target 0 numchars))
        )
        (string-ci=? pfx prefix)
    )
)
; return #t/#f if item exists in the list
; layer: target layer.
; layers: layer list.
(define (contains? layer layers)
    (let*
        ((retv #f))
        (map
            (lambda (lx)
                (if (eqv? lx layer) (set! retv #t))
            )
            layers
        )
        retv
    )
)
; create comma-delimited list of layer names
; list: layer list.
(define (layer-list list)
    (let*
        ((buf ""))
        (for-each
            (lambda (lx)
                (set! buf (string-append (car (gimp-drawable-get-name lx)) "," buf))
            )
            list
        )
        (if (> (string-length buf) 0)
            (set! buf (substring buf 0 (- (string-length buf) 1)))
        )
        buf
    )
)
(script-fu-register
    "script-fu-export-pngs"
    "Create PNGs"
    "Create PNGs from 2 layer subsets"
    "escape-llc"
    "CC 3 Attribution"
    "2009-11-13"
    ""
    SF-FILENAME "Image Filename" ""
    SF-DIRNAME "Output Folder" ""
    SF-STRING "Base Name" ""
    SF-STRING "Factor 1" "color"
    SF-STRING "Factor 2" "glyph"
)
(script-fu-menu-register "script-fu-export-pngs" "<Image>/File/Create")
share|improve this answer
add comment

GIMP supports layers, so the basic idea would be to create a single layer for the button, one layer for each color with a blend mode of some sort to colorize that single button layer, and then individual layers for text. You toggle the visibility of each text layer in turn, and a single color layer for hover state etc.

GIMP also supports scripting, so it is conceivable that one might have a single text layer and a script which would alter the text, iterate through each color state, exporting a jpg of each in turn, then repeat with new text.

I don't use GIMP, so I cannot be more specific. One trick for many programs (but not all) is to record a series of steps using whatever in-built macro system is in place and then edit the steps and wrap a loop around it.

share|improve this answer
add comment

GIMP has something called Script-Fu, which lets you automate most tasks in Scheme. I personally do not now Scheme, so I cannot provide you with a script myself, but the documentation for Script-Fu would be a good place to start. If you decide that using Script-Fu is an acceptable solution, you could check out some basic tutorials to get you started.

However, I must add that if you are only creating a few dozen buttons and you don't happen to know Scheme, you're probably better off doing it by hand, because assuming you have your layers set up efficiently, it shouldn't take you that long.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.