|
|||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionEven the GDI+ methods aren't the most comprehensive. A commonly used image resizing methods are e.g. Nearest Neighbor, Bilinear or Bicubic. These are part of some "standard", but experts and freaks know that these filters doesn't provide as nice images as other filters can. In some software products (especially specialized software for astronomical and medical imaging), we can see filters with strange names like Hermite, Mitchell or Lanczos. These filters works with reference to image's frequency spectra or edges. One of the most unpleasant artifacts is the Moiré effect which can appear while scaling detailed image down. In order to prevent these artifacts, enhance edges and reduce pixelation - more complex filters were designed. In spite of GDI+, filters have big problems with Moiré patterns, they make some artifacts on image borders (it's not an error and can be eliminated, as will be discussed later). This article presents class for image resampling with more precise filters. BackgroundThe first mentoined artifact was the Moiré pattern which appears due to aliasing. This artifact can be seen when one shrinks images without blurring image before zooming, so the high frequencies in the image create a pattern. Samples taken from old images create new frequencies in the new image. This effect is most visible when using a filter with low radius (this filter includes too few adjacent pixels around sample from old image). These examples shows the aliasing artifact produced by a so called Nearest Neighbor filter (first image from left). Much better quality can be obtained by using the GDI+ Low filter (second image - filter has radius 1). Even better quality is provided by the High Quality Bicubic filter (radius 2). Finally, there is the image output from filtering via Lanczos8 filter (radius 8) from the ![]() ![]() ![]()
The original roof image can be found in Wikipedia in the "Moiré pattern" article. It's hard to see, but that last image is sharper than the third one, but there is other more visible defect in the GDI+ resampled version:
This problem can be easily solved using the System.Drawing.Imaging.ImageAttributes attr =
new System.Drawing.Imaging.ImageAttributes();
attr.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
//...
attr.Dispose();
An alternative solution is to set the Graphics grfx = Graphics.FromImage(imgInput);
grfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
Image Resampling with GDI+ FiltersImage resizing (or resampling) is one of the most common functions of every raster image processing tool. If you've decided for GDI+ to resize your images, you can choose from variety of filters. So called Nearest Neighbor (System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor) filter is the fastest one, but it produces blocky artifacts on image stretching because this filter just copies samples from old image to a new image (no interpolation between them). On the contrary, when downsampling by factor 2, every second pixel is lost:
Much better results can be achieved using some interpolation spline. When the image is scaled up, a space between pixels must be filled with some new pixel values. Value of the new pixel can be computed as weighted average of nearest pixel and its neighbors (weights are given by the filter). One of the simplest interpolation/resampling filter is Linear filter (InterpolationMode.Low). The weight of neighboring pixels is a linear function. If you want achieve the "best" quality, then use High Quality Bicubic (InterpolationMode.HighQualityBicubic). This interpolation includes more neighbors in every new pixel value and weights are distributed more effectively (the function is a cubic spline):
The interpolation of the scaled image is done by image filtering, or convolution between image (intensity function) and convolution kernel. If you want closer explanation of how convolution works, see one of the excellent articles from Christian Grauss at this site. He also explains bilinear interpolation. Image Resampling with Custom FiltersNow point our view to ResamplingService.cs. This code file contains few classes for precise resampling. The most important class is There is one class representing common resampling filter: public abstract class ResamplingFilter
When you run the resampling, a new instance of A few people mentioned the fact that older version of this library could not resample images with alpha channel. So I've made it much more versatile after this feedback, primarily by using the Resampling using
In the extreme case, we can compare results on
About the FiltersI've implemented a collection of different resampling filters. Some of them provide even better results than filters in professional imaging applications.
Using the CodeThe project demo solution is extremely simple to understand. All you have to do is to use ResamplingService resamplingService = new ResamplingService();
resamplingService.Filter = ResamplingFilters.CubicBSpline;
ushort[][,] input = ConvertBitmapToArray((Bitmap)imgInput);
ushort[][,] output = resamplingService.Resample(input, nSize.Width,
nSize.Height);
Image imgCustom = (Image)ConvertArrayToBitmap(output);
This code will create a Beyond Conventional MethodsNone of the presented filters (GDI+ or other) can preserve edges, add artifcial detail or do something more on image. Somebody can ask: "And what about that expensive zooming software, that uses edge-enhancing diffusion, adaptive splines or fractals to achieve good visual quality?" The truth is, that these technologies are licensed, but not unknown. Everyone can design some adaptive filter (actual kernel depends on current pixel neighborhood). But these filters are too slow for real-time applications (TV, DVD, games, ...). Yes, of course, it's very practical for photographers. They preserve quality before performance. I'm not familiar with spline approaches, but I've done some investigation on fractals, because it can be used to add good-looking detail into natural images, not only keep image edges. This samples were made by using nontrivial fractal resolution enhancement technique:
Many students on my faculty are interested in digital photography, so the fractal library will be freely available for academic purposes. This is a better choice than very expensive professional zooming software on the market. The only only difference between academic version and the professional is the ratio between quality and speed. PRO software is quick with compromise results, the scientific approach needs to sacrifice tens of minutes to zoom an average-sized image, but the quality gain is sensible (here in 400% zoom)... Original crop of the wood in fall image:
Photoshop's Bicubic filter:
Genuine Fractals PrintPro - top zooming software available:
Our implementation of fractal-based zooming:
ConclusionI hope you've got a brief look onto the resampling topic. We discussed a way how to work with your own filters. To get more information, try to look for some technical articles. You can find several other implementations of resampling methods, but be careful about its properties. I tested my class for many grotesque image sizes (like 1x2397 from 191x2 pixels) and eliminated all artifacts on edges, repairing wrong weight distributions I saw in other sources. One programmer showed me his GUI specialized on resampling. I've discovered and removed a terrible problem, which was causing black and white stripes over all images when reducing its size by an odd factor - of course due to the wrong weight distribution. This was a week before his resampling app became commercial component. I think the presented class is OK, but if you find anything or if you have any ideas how to optimize this common filtering algorithm, I'll be happy to discuss it. Changes in the Last VersionThe code was modified and made more readable (more private access modifiers, global variables reduced, more blank lines, indentation and XML comments). The library works with
|
||||||||||||||||||||||||||||||||||||||||||||||||