Thursday, March 05, 2009

Why You Shouldn't Rotate Your Images In Windows



Ok so I'm being a bit facetious with the title of this post. Using Microsoft's Picture & Fax viewer to rotate images that you've just taken with a digital camera will probably not hurt the image quality to a noticeable amount, for a few reasons. If the image is in the lossy format of Jpeg, it's quite possible that the "lossless" attribute was included and therefore rotating the image shouldn't degrade the image. If not, the sheer size and low compression ratio of the original should absorb all possible degradation for a single rotation of the original image (I show an example of this later on). Finally, if you're the kind of person who'd use Image & Fax viewer to rotate your images to begin with, chances are you're not going to be obsessed with immaculate image detail anyway. Ok, enough with the preamble (Actually this whole post is probably a preamble).


Emillee Cox is a girl that sends over 30,000 text messages from her phone every month. I thought it only fair to rotate her image the same amount of times, but as you can see from the results, she didn't even last for a thousand.

As often happens, I got this notion in my head and I became curious as to exactly how much damage Windows Fax & Image viewer did to a image once it was rotated and then saved again. I tried rotating the image a few times manually, to satisfy my curiosity. I was shocked to see how quickly an image with even a moderate resolution degraded within only a few rotations. On examining the results however, I noticed certain noise patterns emerging. This made me wonder what kind of patterns would emerge if the image was rotated a few hundred or even thousands of times. I decided to write a little program that would automate the process for me.



Unlike Emille in the previous example, Bill Gates was a tough cookie to crack. Even after 30,000 rotations he was still going strong, allbeit looking a bit like a zombie version of Oscar Wilde.


I tried few different files, and there were varying types of image degradation. The two main types however, are the blocky chroma and luminance threshold'ing as seen in the first example, and the other is a type of chaotic noise pattern, where pixel entropy increases until the whole frame is filled with random noise. I find the latter most interesting, as the noise patterns seem to continue indefinitely. As you can see I also included the relative file sizes of each version. It's interesting to note how sometimes the files actually increase in size the more times its compressed (this has to do with the extra fine details created by the noise).

The effect doesn't have to just necessarily "destroy" the image though. With lower rotation amounts, you can create some interesting digital distressed effects, like for example, the bleeding out of the yellow in the loops of the gas pipe in this picture by Donncha O'Caoimh.



And as I mentioned in the opening paragraph, images with large resolutions aren't as affected by the repeated rotation and saving. This image of Irish Green Party member Eamon Ryan lasted very well even at 10,000 rotations.



About the program
I've been getting to grips with VBScript for the last few weeks and as it involved a Windows application using VBScript seemed to be the right language to work with. I could have written a little macro in image editor but this would defeat the novelty of using the Image and Fax viewer plus I'm not immediately sure how I could keep selecting the right file to rotate and compress on the fly.

After a bit of investigating around the internet, I managed to sketch out a little VBscript that could launch the Image Viewer. I was hoping that I could pass it some arguments to make it rotate the image one way or the other but unfortunately, the only argument I could find which it could be passed was the location to an image or group of images. To achieve interaction with the program I had to resort to sending keystrokes to the Windows Shell, which annoyed me as it's quite an inelegant solution. It means that the process can't run in the background as the keystrokes only interact with the window in focus (this means it can be a bit risky if you bring another window into focus while the script is running because god only knows what all the sendkey commands will end up doing).

This is fairly hack&slash code, it's not totally ghetto but it's exception handling isn't the best, so don't try to hard to break it :) When you execute the script, it will allow you to pick a file to use (I've included the extensions .gif and .png as a control). It will then ask you for how many rotations you wish the image to go through. After that it will ask you for a direction choice for the rotations. Once all these have been selected the Image & Fax viewer will pop up with your chosen image. A subdirectory will be created in the same folder as the image. It will be named with the title of image plus "-Project Files". Once running you'll see the image rotated automatically. With each forth rotation, a copy of the current state of the image will be written to the newly created folder. It's every forth rotation simply to keep all the resultant image files "upright" (I've also taken care of only saving upright images in the random mode). If you find any of these files in a rotated orientation afterwards, its probably because your machine wasn't fast enough to keep up with the script. I'll show you how to fix that after I give the links:


DOWNLOAD THE VBSCRIPT HERE
VIEW THE CODE HERE
Before using this code please read the important notice at the end of this post first!
You can simply copy and paste the code, from the "pastie.org" page above, into a text file and save it as "something.vbs". Just double click the resultant file and it should hopefully work. To fix the timing issue I mentioned, open the file in a text editor and locate the two words "startUp" and "runningPause". You'll see a number after an "=" beside them. Experiment with increasing these values. Note the values are in milliseconds, eg 1500 equals 1.5 seconds. There are comments in the code to help anyway.

Animating The Results

Outputting the upright versions of the image allows you to see more easily the degradation of the consecutive rotations, but it also allows you to watch them as a series of frames in an animation to see exactly how the image . If you're used to making your own videos you probably already know how to do this. If you don't however or you couldn't be bothered, there are still a few options open to you. If the images are small, you might be able to open up the first image "1.jpg" in the Picture & Fax viewer and by simply keeping the right arrow key pressed you can watch the images in series fast enough to perceive it as animated. If it begins to flicker however, you'll need to slow it down by repeatedly pressing the key. That becomes painful after a while. So I again wrote a little script to automate this process. It works pretty much like the image rotator vbscript only that there are no files outputted. You can use this for any series of images in a folder so it could turn out to be handy for lots of other situations when speed viewing is needed.

DOWNLOAD THE VBSCRIPT HERE
VIEW THE CODE HERE
Before using this code please read the important notice at the end of this post first!

I used the Obama pic above to give you an example of what to expect, in the video below. I chose this picture because I like how the noise spreads out vertically, it makes it look a bit like the Matrix :) Note: There is some jumping and "blocking" in the frames with this video which has to do with the way the video is keyframed and compressed on Google. The actual source video is very smooth. I gave up on the vimeo version as after multiple uploads of different formats, it still plays worse than Google.



Why did I do all this? I like messing about with stuff like this, images and programming and stuff. Information loss and image degradation in analogue mediums, such as photostatic imaging and VHS cassette tape recording is well known and studied but by their nature, digital reproductions don't degrade with each reproduction (at least they're not meant to) so finding new ways in which they do degrade is interesting. Plus I like chaos. I like it some much in fact that I believe the entire universe is modelled on non-random chaos at the sub quantum level, but that's for another day :)

What now: Personally there a few tweaks I'd like to add to script, dynamic sleep lengths based on the size of the image, more details in the log file, tighter code overall and better error handling. I'd love to dedicate a machine to rotating a hi-res image for a couple of hundreds of thousands of times and see what the resulting hi-res image looks like.

If anyone does anything with this, either extending the code or creating interesting effects I'd love to hear back from them and see what they've come up with ?:-)

N.B. It is the repeated compression of the image that causes the image to degrade, rotation only an added variable.

Important! There's no easy way to terminate the process when it's running. Closing the Image viewer will not stop the script! If you want to stop the process before it's natural end, you'll have to kill the wscript process in Windows Task Manager (CTRL+ALT+DEL). While I can't envisage anything drastic happening to ones machine, the script does send key strokes to the Windows shell so unpredictable things will happen if the Picture & Fax viewer is closed, or looses focus. Use it at your own risk!

16 comments:

Donncha O Caoimh said...

That's mad. From the Green Party images it looks like jpeg artefacts. What quality setting were they saved at, or were the images saved after each rotation?

How many degrees was each rotation?

You could do some neat things with that bleeding colour effect though. :)

Gamma Goblin said...

It looks like you're not too familiar with MS Picture and Fax viewer :) Perhaps I should have explained the application itself a bit more, an oversight on my behalf.

The picture viewer is just the standard Microsoft one that comes with Windows XP onwards. It's primary use is just to view images but it does do some very basic things like Print and slideshow and image rotation. Each rotation covers 90 degree's in either a left or right direction. It's intended use is to upright an image taken with a camera held vertically. Each time the user clicks on the button to rotate the image, the Picture Viewer automatically saves over (modifies) the original file (using an unknown compression amount). What my script does is automate the process (acting as the user) and makes a copy of the modified image file (at the OS level) each time it's rotated; it doesn't handle any interaction with the Image & fax viewers saving algorithms.

In essence, what happens to these images is exactly what would have happened if you kept rotating an image in the viewer manually. It highlights the fact that the rotation of a jpeg is a destructive process (if the "lossless" attribute isn't set).

The cool thing about it that you never really know how an image is going to react when subjected to multiple modifications. I suppose you could study the make-up of an image and predict it, but I prefer leaving it appear like magic :)

Damon Lord said...

I wonder if Gail Trimble would like to be spun round a few times? ;)

Gamma Goblin said...

Oh how did I know that Gail Trimble would get a mention here lol

Bill P. Godfrey said...

I think, if the original image is a multiple of 16 pixels in both directions, it should be possible to perform a loss-less rotation of an image.

Each 16x16 block could be rotated by 90° without losing any information. After that, rotate the arrangement of the blocks so the image is consistent.

Just checked. I'm not the first to think of that. Darn.

Gamma Goblin said...

yes I remember reading something about 16 pixel block thing on my travels. I probably should have paid closer attention to it, so thanks for mentioning it again now :)

Sully said...

That was absolutely fascinating!

Thanks for that - when I was using XP I happily used Picture and Fax viewer since it was so quick to launch, and despite the warning, the loss was negligible - never thought about seeing how deep the rabbit hole went though!

Nice to see someone OCD enough to follow it through!

Gamma Goblin said...

Thanks, I think :) I guess this means I've got lazymans OCD, let the computer do the repeated tasks for you! Now if only I could invent a device to walk over the cracks in the ground for me I'd be set. That's the modern age for you, even people suffering from OCD are turning into couch potatoes! :)

Ambrand.com said...

This has the makings a of a thesis, however we* are both too old for college now, we need jobs

*royal

Gamma Goblin said...

Nonsense! Your never too old to rock'n roll! You know what they say, A Doctorate on the dole is worth two up the hole!

Barry Kelly said...

What you're seeing is an artifact of multiple cycles of decompression / lossy recompression of bitmaps. The fact that it's "in Windows" is besides the point; if you did the 1000 rotations using any other tool, saving to and loading from JPG for each of the 4 steps of the rotation, you'd get similar results.

Gamma Goblin said...

Hi Barry, thanks for your comment. And you're right, you'd get similar results, but I think you missed the main point of my post though. Perhaps in your eagerness to defend Windows you rushed to comment without reading my post in entirety :)

In the first line I point out I'm being facetious with the title of the post. When discussing the VBScript I worte, I made the following confession "I could have written a little macro in an image editor but this would defeat the novelty of using the Image and Fax viewer".

You are slightly flawed in your interpretation of how the Microsoft Image Viewer works too. You suggest that rotating an image 4 times and then saving it will produce the same effect in another program. This is incorrect as the Viewer saves directly after each rotation. That's why it can catch some people out, as it saves automatically without their knowledge or consent, and uses an aggressive compression ratio.

:)

napzter said...

Hey Gamma, have you checked if you get a different result from flipping a picture the other way?

Gamma Goblin said...

Hi napzter! Yes I tried both directions when degrading images but I never compared one against the other using the same image (something I had intended to do). I did discern however that changing the direction randomly for each rotation slowed down the destructive process.

Anonymous said...

@Bill P. Godfrey

Yes, indeed it seems that pretty much everyone else already does lossless JPEG rotation.
http://jpegclub.org/losslessapps.html
Further I've heard that certain drawing software *does* allow you to load/save jpegs in a lossless way if you limit your self to JPEG friendly tools when editing the image.

I assumed that windows would do this very common operation losslessly as well. I guess I really won't rotate my pictures in Windows.

Gamma Goblin said...

Interesting info Anonymous... thanks for that :)

Post a Comment