ImageSizer
Warning: I wrote this blog in 2009. That is a long time ago, especially on the internet. My opinions may have changed since then. Technological progress may have made this information completely obsolete. Proceed with caution.
I wrote a program last week for resizing images so that they can fit onto a two-monitor desktop, and I figured I’d share with the world before heading to the beach. This program does more than just resize an image, though. It accounts for the gap between the two monitors, so that it looks much more like you are looking through the monitors. Most of this post will consist of an explanation of what exactly that means and why you’d want to do it.
Okay, for starters let’s say you have two monitors sitting side-by-side. In our example, these monitors each have a resolution of 304×228 pixels, giving a resolution of 608×228 for the entire desktop. Here is what that looks like:1
Now, let’s say you want to use this photo of the Gizah pyramids by Ricardo Liberato, the #21 finalist for Wikimedia Commons Picture of the Year 2007, as your wallpaper. Here is what the photo looks like initially:
There is a problem here, because that’s not the right proportion, so you’d want to crop out a portion of the image that is the right proportion. Here is a cropped portion that is the proper ratio and size (608×228):
Now, let’s use that image as our desktop wallpaper on our dual-monitor setup:
I don’t know about you, but I find this very aesthetically displeasing. Suddenly the pyramid is not shaped like a pyramid anymore! Your mind expects the image to continue through the space between the monitors, but it actually just picks up where it left off on the edge of the other screen. In fact, it kinda makes it look like there is a fourth, smaller pyramid, between the first and second one.
So here’s where my app comes in. We need to figure out how wide that gap is, in pixels. If you knew the dpi of your monitor, you could measure the gap in inches and calculate the number of pixels. But if you don’t know that, here’s how I measure it. Open up any kind of image editing app (Paint will do just fine). Place the window so that it straddles the gap between monitors. Draw a 45-degree line that spans the monitors. It is very important that the line be exactly 45 degrees (you can hold control or shift or something to fix the line to 45 degrees in most image editing apps). Now, hold something with a straight edge (say, a piece of paper) so that it lines up with the line on one monitor. Holding the straight edge there, click somewhere on the other monitor, where the line would be if it was accounting for the gap, and draw another 45-degree line starting from there. Now measure the vertical distance, in pixels, between the two lines. This will be equivalent to the horizontal distance, in pixels, between the two monitors. For our example, here is what that might look like:
You can see the solid black line is “straight” if the gap is not accounted for. However, the dashed line shows how the line would behave if the gap was considered to have a width. The distance between the dashed line and the solid line on the right-hand monitor is 50 pixels, so that is the width of our gap. So now, let’s use my app:
java -jar ImageSizer.jar pyramids.jpg -monitorWidth 304 -height 228 -gap 50
This will generate pyramids.resized.png, which looks like this:
When we use this image as our desktop wallpaper, we get an image that looks correct:
If you’d like the program, you can download the source right here. But before you use it, here are a few things you should know:
- You may get OutOfMemory exceptions on very large images. If this happens (thanks Peter), you can increase the Java heap size from the command line like this: java -Xmx256m -jar ImageSizer.jar .... If that still doesn’t work, increase the 256 to a bigger number. It is important that the -Xmx parameter comes before the -jar parameter, so that Java knows it is a parameter to the JVM and not to the ImageSizer.
- When the image is not the proper proportion (which will be nearly all the time), it will crop from the middle of the image. In many cases, this will be a less-than-ideal cropping. If that happens, you should crop the image the way you want it cropped first. (The tool will still help you out because removing the middle of an image is much more tedious.)
- Your monitors must be of equal resolution.
- Supported file types are .jpg, .png, and (I think) .bmp and .gif. (I’ve only tested jpg and png myself though.)
- Output file will always be .png format, even if a different extension is used on output file. This is important because a lossy compression can cause some pixels to “bleed” between the monitors.
- There is only support for two-monitor setups.
- If you want to modify the code, feel free to do so. You can even redistribute if you want, just be sure to leave my name and URL in the comments and help info. The source is included in the jar file (open it as a zip file). There are only two Java files.
- There is a good chance there are some bugs, as this was written in two evenings, with a fourteen-month-old competing with the computer for my attention. The vast majority of that time was spent trying to figure out how to use the Java image libraries. I probably could have written this in PHP in an hour, but I didn’t want to use PHP from the command line, and I didn’t want to have to upload large images.