WPF Image Manipulation Woes
My work in WPF image manipulation lately has made me question just how good an idea it is to have WPF measurements not tied to pixels, but rather device-independent-units. I understand the theoretical benefits of the design such as controls automatically being able to scale to the correct size regardless of screen resolution, but when trying to manipulate images this all becomes another layer of abstraction which makes everything more difficult.
The primary issue is the translation between what image is being displayed on the screen and the actual image size. For example, if a bitmap is 300×300 pixels the ActualHeight and ActualWidth of the Image object (System.Windows.Controls.Image) that the bitmap is associated with could be anything…from 15×15 to 1000×1000 device-independent-units. Yet, for the purposes of image manipulation the original image size always has to be used, because even if an image is displayed at 1000×1000 device-independent-units, the actual number of pixels contained in the BitmapSource is still 300×300. Great.
So, now we are left with having to manipulate the original bitmap and resizing/scaling it up to the display size. This is probably only a minor headache when dealing with 1 original image and 1 manipulated image, but when dealing with 1 original image decomposed into 1000’s of composite images it becomes problematical.
This became apparent while working on my current project, the Infinite Image Engine. The framework takes a source image, decomposes it into hundreds or thousands of swaths of average color, and then recomposes it using a database of images matching each swath to an image of similar average color. It is fairly straightforward when the source image size displayed matches the actual image size, but decidedly not so otherwise.
The primary problem is that the most convenient image manipulation handles are found in the Image’s BitmapSource (Image.Source). This has methods to copy pixels and modify pixel values, but it is all based on the original bitmap’s pixel sizes and does not reflect the display size. This is by-design, but that doesn’t leave developers with any built-in options to manipulate on-screen images. Instead we are left to create an abstraction layer to do the translation between the display size and the original image size. While this is certainly doable, it wouldn’t be my first or even second choice for how to get things done. If we are going to be stuck with device-independent-units in WPF, and overall I think it is a good design, then the measurement should be ubiquitous throughout the system, including at the BitmapSource level.
Michael G. Emmons
August 23rd, 2007 at 7:10 pm
Just a quick question … I have an image control that stretches the source image to the size of the control (maintaining aspect ratio). Is there a way to determine the actual render size of the image?