Automated GIMP Processing of Web Site Images
Listing 8. Show layers that have a name matching the given regular expression.
sub Layers_showByRE {
my( $img, $layersre ) = @_;
@layers = Gimp->image_get_layers( $img );
foreach $l (@layers) {
$n = Gimp->layer_get_name( $l );
if( $n =~ m/$layersre/ )
{
Gimp->layer_set_visible( $l, 1 );
}
}
}
...
sub monkeyiq_gimp_layers_hideall {
my($inputimagename,$outfilename,$layersre) = @_;
$img = gimp_file_load( $inputimagename,
$inputimagename );
Layers_showByRE( $img, $layersre );
gimp_xcf_save( 0, $img, 0,
$outfilename, $outfilename );
gimp_image_delete( $img );
}
Let's look at one more simple script before moving on. The generation of prelight images for mouse-over events can be automated by adjusting the brightness or contrast of each layer.
The script and its arguments are shown in Listing 9. A slight bump in brightness (say to 5 or 10) is usually enough to make a quick prelight image for many images.
Listing 9. Create a quick prelight image for mouse-over events.
...
sub monkeyiq_gimp_prelight {
my($inputimagename,$outfilename,
$brightness, $contrast ) = @_;
$img = gimp_file_load( $inputimagename,
$inputimagename );
print "prelight $inputimagename";
print " to $outfilename\n";
@layers = gimp_image_get_layers( $img );
foreach $l (@layers)
{
gimp_brightness_contrast( $l,
$brightness, $contrast );
}
imageOutput( $img, $outfilename );
}
...
"*",
[
[PF_STRING, "inputimage",
"Name of image to export", ""],
[PF_STRING, "outputimage",
"Name of image to save to", ""],
[PF_INT, "brightness",
"-127 to 127", ""],
[PF_INT, "contrast",
"-127 to 127", ""],
],
...
Now, suppose we have a directory full of xcf files of product images and we want to composite all those images onto a background image and save them to JPEG files with the same base name. This can be driven from a Makefile as shown in Listing 10. The Makefile defines a JPEG target for every xcf file in the current directory. Each of these JPEG targets are processed the same way, and the JPEG file is dependent on its xcf file. If you change one of The GIMP product images (xcf files), the Makefile will reprocess only that xcf file.
A thumbnail image also is created for each product. The catch here is that the thumbnail is expected to be displayed at a different offset on the background image. This means the thumbnail has to have all the image data shifted relative to the background prior to scaling and saving. If many products are to be shown on a single page, the call to gimp-monkeyiq-move-visible-layers would have to work out which offset to use for each thumbnail to make the blend with the background image pleasing when shown on the Web site.
Listing 10. Makefile to Convert xcf Files to Composited JPEG Images
tmp_img=/tmp/tmp_img.xcf
tmp2_img=/tmp/tmp_img.xcf
background_img=mybackground.png
simplelayered_extension=xcf
simplelayered_targets=\
$(patsubst %.xcf,%.jpg,$(wildcard *.xcf))
all: $(simplelayered_targets)
$(simplelayered_targets): %.jpg: %.xcf
if_xcf=$<; \
if=`basename $< .xcf`.png \
of=$@; \
of_thumbnail=`basename $@ .jpg`-thumb.jpg \
gimp-monkeyiq-append-layer-from-image-file \
-inputimage `pwd`/$$if_xcf \
-outputimage $(tmp_img) \
-layerimage `pwd`/$(background_img) \
-layername "background-layer"; \
gimp-monkeyiq-save-as-jpg \
-inputimage $(tmp_img)
-outputimage $$of; \
gimp-monkeyiq-scale \
-inputimage `pwd`/$$if_xcf \
-outputimage $(tmp_img); \
-ratio 0.15; \
gimp-monkeyiq-append-layer-from-image-file \
-inputimage $(tmp_img) \
-outputimage $(tmp2_img) \
-layerimage `pwd`/$(background_img) \
-layername "background-layer"; \
gimp-monkeyiq-layers-showall \
-inputimage $(tmp2_img) \
-outputimage $(tmp_img); \
gimp-monkeyiq-layers-hidebyre \
-inputimage $(tmp_img) \
-outputimage $(tmp2_img) \
-layersre "background-layer"; \
gimp-monkeyiq-move-visible-layers \
-inputimage $(tmp2_img) \
-outputimage $(tmp_img) \
-xoffset 200 -yoffset 100; \
gimp-monkeyiq-save-as-jpg \
-inputimage $(tmp_img)
-outputimage $$of;
Let's start from the simple and move to the more complex scripts from Listing 10. The gimp-monkeyiq-save-as-jpg script is shown in Listing 11. The getMergedLayer() function is from the MonkeyIQGIMP module shown in Listing 3. It gets all the visible layers as a single merged layer. Given a single layer, it can be exported as a JPEG, and I use the specific JPEG save GIMP function to allow various parameters specific to JPEG image compression to be set. Apart from the image in/out parameters, the two main parameters are quality and comment. Being able to embed a comment in the JPEG image itself allows metadata to be added to the Web image, such as an image copyright and author data string.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
| Introduction to MapReduce with Hadoop on Linux | Jun 05, 2013 |
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Linux Systems Administrator
- RSS Feeds
- Introduction to MapReduce with Hadoop on Linux
- Validate an E-Mail Address with PHP, the Right Way
- Weechat, Irssi's Little Brother
- Tech Tip: Really Simple HTTP Server with Python
- New Products
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




47 min 47 sec ago
48 min 47 sec ago
1 hour 34 min ago
2 hours 22 min ago
2 hours 46 min ago
4 hours 23 min ago
4 hours 24 min ago
6 hours 17 min ago
9 hours 7 min ago
14 hours 20 min ago