Shallow Thoughts : : gimp
Akkana's Musings on Open Source Computing, Science, and Nature.
Wed, 27 Feb 2013
I was printing out a map for a new trail we wanted to hike.
I wanted to fill the paper with the map -- Google maps' print and
Firefox's print, while fine for most map printing, weren't what I wanted.
So I took a screenshot of the maximized browser window with the map in it
and imported it into GIMP. In the Crop tool, I constrained Aspect-ratio
to 11:8.5 and cropped the image so it would just fit on a page, in
landscape format -- wider in east-west than in north-south.
Then I chose File->Print.
Since printing defaults to Portrait orientation,
I went to the Page Setup tab and changed Orientation to Landscape.
(It's so nice to have that as part of the dialog. I'm forever amazed
at how some apps, like Firefox, make you use a separate dialog first
to change the print's orientation.
How can anyone possibly see that as sensible UI design?)
Unfortunately, When I went to the Image Settings tab to check ,
I discovered that GIMP hadn't adjusted the image size when I changed
to Landscape. It had Width listed as 8.500, Height as 6.567, and the
image only took up part of the page.
I went to the Width field and replaced 8.500 with 11, and hit
Tab. Whoops! The field reverted to 8.500. The same thing happened
if I tried typing 8.5 into the Height field.
These fields aren't plain text entries -- they're "spin boxes", with
a text entry plus up and down arrows.
It turned out that under GIMP 2.8 and earlier, round-off errors sometimes
prevent you from setting a spin box's maximum value. I could type 10.999
and it would work fine, but 11 or 11.0 failed.
Of course, 10.999 would have been fine -- I don't mind a little margin
on a printed map. It's also trivial in GIMP to rotate a landscape photo
90 degrees and print it in portrait orientation. But by this point
I was into stubborn mode -- by gosh, I wanted a way to fix this!
The best workaround, it turns out, is to use the spin box's up-arrow.
Holding the mouse down over the up arrow will eventually get to the
maximum value. But there's a faster way: right-clicking
on the up-arrow goes straight to the maximum value. A nice trick!
The problem doesn't exist in GIMP 2.9 -- I reported it as
bug 694477,
and the awesome GIMP team fixed it very quickly.
The spin boxes work beautifully now. (Thanks, Mitch!)
But as long as 2.8 is around, or for any other app using spin boxes,
I'm glad to know about right-clicking on the spin box arrows.
Tags: gimp, printing
[
11:26 Feb 27, 2013
More gimp |
permalink to this entry |
comments
]
Sun, 02 Sep 2012
In a discussion on Google+arising from my
Save/Export
clean plug-in, someone said to the world in general
PLEASE provide an option to select the size of the export. Having to
scale the XCF then export then throw out the result without saving is
really awkward.
I thought, What a good idea! Suppose you're editing a large image, with
layers and text and other jazz, saving in GIMP's native XCF format,
but you want to export a smaller version for the web. Every time you
make a significant change, you have to: Scale (remembering the scale
size or percentage you're targeting);
Save a Copy (or Export in GIMP 2.8);
then Undo the Scale.
If you forget the Undo, you're in deep trouble and might end up
overwriting the XCF original with a scaled-down version.
If I had a plug-in that would export to another file type (such
as JPG) with a scale factor, remembering that scale factor
so I didn't have to, it would save me both effort and risk.
And that sounded pretty easy to write,
using some of the tricks I'd learned from my Save/Export Clean
and wallpaper
scripts.
So I wrote export-scaled.py
It's still brand new, so if anyone tries it, I'd appreciate knowing
if it's useful or if you have any problems with it.
Geeky programming commentary
(Folks not interested in the programming details can stop reading now.)
Linked input fields
One fun project was writing a set of linked text entries for the dialog:
| Scale to: | Percentage 100 %
| Width: 640 | Height: 480
|
Change any one of the three, and the other two change automatically.
There's no chain link between width and height:
It's assumed that if you're exporting a scaled copy, you won't want
to change the image's aspect ratio, so any one of the three is enough.
That turned out to be surprisingly hard to do with GTK SpinBoxes:
I had to read their values as strings and parse them,
because the numeric values kept snapping back
to their original values as soon as focus went to another field.
Image parasites
Another fun challenge was how to save the scale ratio, so the second
time you call up the plug-in on the same image it uses whatever values
you used the first time. If you're going to scale to 50%, you don't
want to have to type that in every time. And of course, you want it
to remember the exported file path, so you don't have to navigate
there every time.
For that, I used GIMP parasites: little arbitrary pieces of data you
can attach to any image. I've known about parasites for a long time,
but I'd never had occasion to use them in a Python plug-in before.
I was pleased to find that they were documented in the
official GIMP
Python documentation, and they worked just as documented.
It was easy to test them, too: in the Python console
(Filters->Python->Console...), type something like
img = gimp_image_list()[0]
img.parasite_list()
img.parasite_find(img.parasite_list()[0])
and so forth. Nice!
Not prompting for JPG settings
My plug-in was almost done. But when I ran it and told it to save to
filenamecopy.jpg, it prompted me with that annoying JPEG
settings dialog.
Okay, being prompted once isn't so bad. But then
when I exported a second time, it prompted me again,
and didn't remember the values from before.
So the question was, what controls whether the settings dialog is
shown, and how could I prevent it?
Of course, I could prompt the user for JPEG quality, then call
jpeg-save-file directly -- but what if you want to export to PNG
or GIF or some other format? I needed something more general
Turns out, nobody really remembers how this works, and it's not
documented anywhere. Some people thought that passing
run_mode=RUN_WITH_LAST_VALS when I called
pdb.gimp_file_save() would do the trick, but it didn't help.
So I guessed that there might be a parasite that was storing those
settings: if the JPEG save plug-in sees the parasite, it uses those
values and doesn't prompt. Using the Python console technique I just
mentioned, I tried checking the parasites on a newly created image
and on an image read in from an existing JPG file, then saving each
one as JPG and checking the parasite list afterward.
Bingo! When you read in a JPG file, it has a parasite called
'jpeg-settings'. (The new image doesn't have this, naturally).
But after you write a file to JPG from within GIMP, it has not
only 'jpeg-settings' but also a second parasite, 'jpeg-save-options'.
So I made the plug-in check the scaled image after saving it,
looking for any parasites with names ending in either -settings
or -save-options; any such parasites are copied to the
original image. Then, the next time you invoke Export Scaled, it does
the same search, and copies those parasites to the scaled image before
calling gimp-file-save.
That darned invisible JPG settings dialog
One niggling annoyance remained.
The first time you get the JPG settings dialog, it
pops up invisibly, under the Export dialog you're using. So if
you didn't know to look for it by moving the dialog, you'd think the
plug-in had frozen. GIMP 2.6 had a bug where that happened every time
I saved, so I assumed there was nothing I can do about it.
GIMP 2.8 has fixed that bug -- yet it still happened
when my plug-in called gimp_file_save: the JPG dialog popped
up under the currently active dialog, at least under Openbox.
There isn't any way to pass window IDs through gimp_file_save so
the JPG dialog pops up as transient to a particular window. But a few
days after I wrote the export-scaled, I realized there was still
something I could do: hide the dialog when the user clicks Save.
Then make sure that I show it again if any errors occur during saving.
Of course, it wasn't quite that simple. Calling chooser.hide()
by itself does nothing, because X is asynchronous and things don't happen
in any predictable order. But it's possible to force X to sync the display:
chooser.get_display().sync().
I'm not sure how robust this is going to be -- but it seems to work well
in the testing I've done so far, and it's really nice to get that huge
GTK file chooser dialog out of the way as soon as possible.
Tags: gimp, programming, python
[
17:34 Sep 02, 2012
More gimp |
permalink to this entry |
comments
]
Tue, 21 Aug 2012
In GIMP 2.8, the developers changed the way you save files. "Save" is
now used only for GIMP's native format, XCF (and compressed variants
like .xcf.gz and .xcf.bz2). Other formats that may lose information on
layers, fonts and other aspects of the edited image must be "Exported"
rather than saved.
This has caused much consternation and flameage on the gimp-user
mailing list, especially from people who use GIMP primarily for
simple edits to JPEG or PNG files.
I don't particularly like the new model myself. Sometimes I use GIMP
in the way the developers are encouraging, adding dozens of layers,
fonts, layer masks and other effects. Much more often, I use GIMP
to crop and rescale a handful of JPG photos I took with my camera on a hike.
While I found it easy enough to adapt to using
Ctrl-E (Export) instead of Ctrl-S (Save), it was annoying that when I
exited the app, I'd always get am "Unsaved images" warning, and it was
impossible to tell from the warning dialog which images were safely
exported and which might not have been saved or exported at all.
But flaming on the mailing lists, much as some people seem to enjoy it
(500 messages on the subject and still counting!)
wasn't the answer. The developers have stated very clearly that they're
not going to change the model back. So is there another solution?
Yes -- a very simple solution, in fact. Write a plug-in that saves or
exports the current image back to its current file name, then marks it
as clean so GIMP won't warn about it when you quit.
It turned out to be extremely easy to write, and you can get it here:
GIMP: Save/export
clean plug-in. If it suits your GIMP workflow, you can even
bind it to Ctrl-S ... or any other key you like.
Warning: I deliberately did not add any "Are you sure you want
to overwrite?" confirmation dialogs. This plug-in will overwrite
your current file, without asking for permission. After all, that's its
job. So be aware of that.
How it's written
Here are some details about how it works.
Non software geeks can skip the rest of this article.
When I first looked into writing this, I was amazed at how simple it was:
really just two lines of Python (plus the usual plug-in registration
boilerplate).
pdb.gimp_file_save(img, drawable, img.filename, img.filename)
pdb.gimp_image_clean_all(img)
The first line saves the image back to its current filename.
(The gimp-file-save PDB call still handles all types, not just XCF.)
The second line marks the image as clean.
Both of those are PDB calls, which means that people who don't have
GIMP Python could write script-fu to do this part.
So why didn't I use script-fu? Because I quickly found that if I bound
the plug-in to Ctrl-S, I'd want to use it for new images -- images that
don't have a filename yet. And for that, you need to pop up some sort
of "Save as" dialog -- something Python can do easily, and Script-fu
can't do at all.
A Save-as dialog with smart directory default
I couldn't use the
standard GIMP save-as dialog: as far as I can tell, there's
no way to call that dialog from a plug-in.
But it turned out the GTK save-as dialog has no default directory to
start in: you have to set the starting directory every time. So I
needed a reasonable initial directory.
I didn't want to come up with some desktop twaddle like ~/My Pictures
or whatever -- is there really anyone that model fits? Certainly not me.
I debated maintaining a preference you could set, or saving the last
used directory as a preference, but that complicates things and I
wasn't sure it's really that helpful for most people anyway.
So I thought about where I usually want to save images in a GIMP session.
Usually, I want to save them to the same directory where I've been saving
other images in the same session, right?
I can figure that out by looping through all currently open images
with for img in gimp.image_list() : and checking
os.path.dirname(img.filename) for each one.
Keep track of how many times each directory is being used;
whichever is used the most times is probably where the user wants
to store the next image.
Keeping count in Python
Looping through is easy, but what's the cleanest, most Pythonic way
of maintaining the count for each directory and finding the most
popular one? Naturally, Python has a class for that,
collections.Counter.
Once I've counted everything, I can ask for the most common path.
The code looks a bit complicated because
most_common(1) returns a one-item list of a tuple of the single
most common path and the number of times it's been used -- for instance,
[ ('/home/akkana/public_html/images/birds', 5) ].
So the path is the first element of the first element, or
most_common(1)[0][0]. Put it together:
counts = collections.Counter()
for img in gimp.image_list() :
if img.filename :
counts[os.path.dirname(img.filename)] += 1
try :
return counts.most_common(1)[0][0]
except :
return None
So that's the only tricky part of this plug-in.
The rest is straightforward, and you can read the code on
GitHub:
save-export-clean.py.
Tags: gimp, programming, python
[
11:26 Aug 21, 2012
More gimp |
permalink to this entry |
comments
]
Wed, 13 Apr 2011
Are you a GIMP user or Summer of Code student who's been
wanting to get involved,
but having trouble building, or a bit intimidated by the build process?
I'll be running a session on IRC to help anyone build GIMP
on Linux, as part of the
OpenHatch "Build it"
project.
The session will take place on #gimp on irc.gimp.org (also known as
GimpNet), on Fri, Apr 15, 0300 UTC -- that's Thursday
night in the Americas. To convert to your time zone,
run this command on your local machine:
$ date -d 'Fri Apr 15 03:00 UTC'
Thu Apr 14 20:00:00 PDT 2011
Or try this link:
world
time server.
This is a time that's usually fairly quiet on #gimp -- European users
don't fret, since it's pretty
easy to get help there during more Europe-friendly time zones.
I'll hang around for at least two hours; that should be plenty of
time to build GIMP and all its prerequisites.
For folks new to IRC, note that irc.gimp.org is its own server --
this is not the #gimp channel on Freenode. You can learn more about
IRC on the LinuxChix IRC for
Beginners page, or, if you have trouble getting an IRC client
configured, try this link for
mibbit
web chat.
Note: The #gimp IRC channel was recently under attack by trolls,
and it's possible that it may not be usable at the time of the session.
In that case, I will update this blog page with the name of an
alternate channel to use, and any other necessarily details.
Preparation
If you want to get your system set up ahead of time, I've put the
instructions needed to build on Ubuntu Lucid and other older Linux
distros here:
Gimp Building
Tips (for Linux).
I might be able to offer a little help with building on Macs,
but no guarantees.
Mac and Windows users, or people running a very old Linux distro
(more than a year old) might want to consider an alternate approach:
install Virtualbox or
VMware and install Ubuntu "Natty
Narwhal" (currently still in beta) in a virtual machine.
Of course, this isn't the only time you can get help with building GIMP.
There are folks around on #gimp most of the time who are happy to
help with problems. But if you've been meaning to get started and
want a good excuse, or you've been holding off on asking for help ...
come hang out with us and try it!
Tags: gimp, programming, education
[
11:50 Apr 13, 2011
More gimp |
permalink to this entry |
comments
]
Sat, 19 Feb 2011
A couple of people recently have appeared on GIMP IRC channels
wondering why no filters or layer operations seemed to work in GIMP,
even though they had an image open.
In at least one case, it was a setting most of us had forgotten about:
the Auto button. It's easy to miss, but if you turn it on accidentally,
you may be unable to do anything in GIMP until you realize what's happened.
The Auto button is the one at the upper right of your Layers dialog.
It's on by default, and what it does is ensure that dialogs like Layers,
and GIMP's notion of the currently active layer, follow the active image.
Open a new image, or click in a different image window, and your Layers
dialog switches images -- so whatever you do next will apply to the
image you just chose.
If you turn Auto off, then by default, no image and no layer
is active. Notice, in the screenshot at left, how no image is shown
in the option menu just left of the Auto button.
Even if you open a new image, you can't do anything with it
until you explicitly choose an image from the menu.
I'm sure you can see why this could be confusing. So why have that
button at all?
Well, it's useful when you're working with lots of images -- for
instance, if you want to drag a layer from one image into another
image, you can use the menu to switch quickly among images and layers
without needing to bring those image windows to the front.
I don't find I need it, but for those who do, I guess it can
be a real time-saver.
Just to make it even more confusing, not everyone even has the
Auto button or the menu next to it. You can turn it off (and gain a
little extra vertical space for your layers dialog) with the tiny menu
button right above the mode menu. "Show Image Selection" controls
whether the image option menu, and the Auto button next to it, will
be displayed. "Auto Follow Active Image" is the same toggle as the
Auto button itself.
So if you ever get stuck and the Layers dialog doesn't seem to be
showing layers from your image, and you can't figure out why ...
remember that pesky Auto button. It might just be the problem.
(If not, try quitting GIMP and moving your profile aside. That works
for curing all manner of mysterious ills -- including this one.
Come to think of it, that deserves an article of its own. Coming soon!)
Tags: gimp, ui
[
10:04 Feb 19, 2011
More gimp |
permalink to this entry |
comments
]
Fri, 18 Feb 2011
![[arrow]](http://shallowsky.com/blog/images/screenshots/nw-arrow.jpg)
While writing a blog post on GIMP's confusing Auto button (to be
posted soon), I needed some arrows, and discovered a bug in my
Arrow Designer script when making arrows that are mostly vertical.
So I fixed it. You can get the new Arrow Designer 0.5 on my
GIMP
Arrow Designer page.
It's purely a coincidence that I discovered this a week before
SCALE, where I'll be speaking on
Writing
GIMP Scripts and Plug-Ins.
Arrow Designer is one of my showpieces for making interactive
plug-ins with GIMP-Python, so I'm glad I noticed the bug when I did.
Tags: gimp, programming, python
[
20:28 Feb 18, 2011
More gimp |
permalink to this entry |
comments
]
Thu, 23 Dec 2010
Have a lot of images to edit, but confused by command-line tools
like ImageMagick? Try David's Batch Processor, a GIMP plug-in that
lets you apply multiple operations like resize, rotate, or
brightness/contrast to groups of photos.
The article is on Linux Planet:
Editing
Batches of Photos Easily on Linux.
Tags: writing, gimp
[
10:07 Dec 23, 2010
More gimp |
permalink to this entry |
comments
]
Mon, 15 Nov 2010
My previous Linux Planet article covered beginner tips for cutting
foreground objects out of photographs. Part 2, from last week,
covers some more flexible advanced techniques you'll want to use as your
GIMP skills increase.
Find out how to put a butterfly in space!
Read it here:
More GIMP
tricks for cutting objects of photos
Tags: writing, gimp
[
14:14 Nov 15, 2010
More gimp |
permalink to this entry |
comments
]