Showing posts with label images. Show all posts
Showing posts with label images. Show all posts

Saturday, 10 November 2012

Batch resize images to a fixed width and add watermarks

Problem:

I've got a bunch of images that I want to make a resized version of to post online. Additionally, I want to add a watermark to each of these resized images. I already have ImageMagick installed in my OS X or Linux computer.

Solution:

This is quite a specific problem with a very specific solution. This post assumes that you have read and understood the previous post found here. If not, the solution in this blog post should still be somewhat clear, if not a little fast-paced.

For the sake of this post, let's assume that the source images are a bunch of .JPG images. Additionally, let's assume that we want to resize our images to a width of 320 pixels while maintaining the aspect ratio of the original image. Finally, let's assume that we want to give our images the semi-transparent watermark "grammarofdev.blogspot.com", using the font located at "/Library/Fonts/Arial.ttf". To prevent overriding our original images, we will also create a new sub-folder called 'results'. Below is an example Terminal command of how to do all of this (with line-breaks added for legibility):

$ mkdir ./results
$ mogrify -font /Library/Fonts/Arial.ttf -pointsize 88 -verbose
          -draw "fill rgba(255,255,255,0.5) text 24,75
                 'grammarofdev.blogspot.com'"
          -path ./results -resize 320 -quality 86 -format jpg *.JPG

Phew, what an ugly, long command. What does it all mean?

The "-font /Library/Fonts/Arial.ttf -pointsize 88" selects the Arial TrueType font with a point-size of 88pt. The "-verbose" flag outputs verbose information to the terminal while the conversion is being done. The "-draw "fill rgba(255,255,255,0.5) text 30,80 'grammarofdev.blogspot.com'"" portion tells ImageMagick to render the text "grammarofdev.blogspot.com" with a fill colour of white and an alpha of 0.5, starting at the (x,y) coordinate of (24,75) of the original image.

The "-path ./results" indicates that the resized images should be written to the "results" sub-folder. Note that all files in that sub-folder with the same name will be written over without warning! Additionally, omitting this flag will write over all of your original images!

Next, "-resize 320 -quality 86 -format jpg" indicates that the images should be resized to have a width of 320 pixels, maintaining the original aspect-ratio, and then converted to jpeg with a quality of 86. Finally "*.JPG" indicates that this command should convert all images with the suffix .JPG (case-sensitive).

Note that the text is drawn onto the original image prior to the image being scaled down to the final desired size.

Let's see how well this worked. The following two images will show an image before this command is run, and the resulting image afterwards. Note that the original image dimensions are 3264x2448 pixels, however this image is not included in this post. (A slightly-larger version can be found here!)

Original image (scaled to width 300px):

Watermarked image:

Where can this be useful:

Imagine that you had a hundred images you wanted to automatically watermark and resize, or imagine that you have created a web app that requires re-sizing and watermarking previews of images. Using ImageMagick to perform this task is a quick way to achieve the desired results without needing to program anything complex, or use programs such as Photoshop. This post only touched the surface of what ImageMagick can do. For more details on resizing, or details on drawing on images automatically with ImageMagick, check out the following references.


References:

Friday, 9 November 2012

Batch convert PNG images to 50% scaled jpg images with mogrify

Problem:

How do I convert a bunch of PNG images to jpeg images at 50% of their original dimensions? I'm on an OS X computer and have already installed ImageMagick.

Solution:

You can use the 'mogrify' command that comes with ImageMagick in the Terminal. Note however, that mogrify has the ability to silently overwrite images, so *be careful*! In the following example a destination folder is created to save images in order to preserve the original images.

$ mkdir ./results
$ mogrify -path ./results -resize 50x50% -quality 80 -format jpg *.PNG

So what did all of that mean?

The first part, "mkdir ./results" created a sub-folder named 'results' to save all of the converted images. You can make a different sub-folder if you already have a folder named 'results' to avoid overwriting contents in that existing sub-folder. Remember to change the folder in the -path portion of the mogrify command, too.

The next part batch converts all of the .PNG images to .jpg images of half the width and height. Note that the extensions are case-sensitive. The "-path ./results" flag indicates that results of the conversion are written to the "./results" folder. All destination images are overwritten if they already exist. The "-resize 50x50%" portion shrinks the final width and height to 50% of the original. The "-quality 80" indicates the compression level of the resulting jpeg images. The "-format jpg" indicates that the final image format should be jpeg. Finally, the "*.PNG" indicates that the input images will be every .PNG image in the current folder.

References:

Sunday, 29 April 2012

Web script measuring sizes of images or divs breaks the first time, but not the rest with Javascript or JQuery

Problem:

A script that uses the width or height function to measure a loaded div or an image seems to break the first time the page is loaded, but not any subsequent times.

Possible diagnosis:

There are actually two problems in the above situation. The first problem is that the bug seemingly cannot be reproduced. The second problem is that the script will break for any users seeing the containing page for the first time.

One situation where this can occur is because the script is run by the browser prior to an image being loaded. For instance, the following example script can have this error occur:

$(document).ready(function(){
var divWidth = $("#mydivwithanimage").width();
doSomethingImportantWithWidth(divWidth);
});

The reason this script fails is because even though JQuery waits until the DOM is loaded prior to executing this script, this doesn't necessarily mean that other page components being loaded, such as images, have completed loading before this script is run. This leads to the funny problem that the script will only fail the first time it is run in an open browser, as the browser will cache all loaded images and other page components and often load them before the script is run when the page is reloaded.

Solution (for debugging):

The solution to reproducing this error while debugging is to clear all browser caches (javascript variables as well as loaded components) prior to re-running the script. In Firefox, you can simply clear your cache prior to completely quitting your browser. This should work with most other browsers, too. After re-launching the browser, the bug should appear once again.

Solution:

To correct the script, you need to ensure that it is run after all page components, such as images, are loaded, and not simply just the DOM. If you are using JQuery, rather than using $(document).ready(), use $(window).load(), e.g.

$(window).load(function(){
// ... your stuff here ...
});

For regular javascript, you can use the 'complete' property, e.g.

var myImage = new Image();
myImage.src = "img/myimage.png";

// ... later on ...
if(myImage.complete){
// ... do stuff ...
}