You are on page 1of 14

11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

15,492,942 members 747


articles Q&A forums stuff lounge ? Search for articles, questions,

Watch

Image Processing for Dummies with


C# and GDI+ Part 5 - Displacement
filters, including swirl
Christian Graus Rate me: 4.90/5 (146 votes)

26 Dec 2002

In the fifth installment, we build a framework for generating filters that work by changing a pixel's
location, rather than colour.

Is your email address OK? You are signed up for our newsletters or notifications but
your email address is either unconfirmed, or has not been reconfirmed in a long time.
Please click here to have a confirmation email sent so we can start sending you
newsletters again.

Download source files - 37.5 Kb


Download demo project - 14.6 Kb

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 1/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Introduction
Welcome again to my series on image processing. This time around I want to talk about
displacement filters. Most of the information you'll find about image processing is similar to the
previous articles, talking about changing an image
by changing the colour values of pixels. Instead
the filters we are looking at today change an image by changing each pixels location. I got a lot of
email for my last article, asking why I bothered writing code to resize images. The answer was that
the last article explains bilinear filtering, a way of moving pixels so they are drawn to a theoretical
location between physical pixels. We will use that ability in this article, but I will not explain it,
instead I recommend that you review the prior article[^] if you are not familiar with bilinear filtering.

The framework
Once again we will start by implementing a frame work which we can use to create filters. Our basic
approach will be to create a two dimensional array of points. The array will be the size of the image,
and each point will store the new location for the pixel at that index. We will do this two ways, one
that stores a relative location, and one that stores an absolute location. Finally, we will create our
own point struct, which contains two doubles instead of ints, which we will use to write the
implementation to performs the bilinear filtering.

Arrays in C#
I must admit I had not done anything with 2D arrays in C# before this, and they are very cool. The
code looks like this:

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 2/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Point [,] pt = new Point[nWidth, nHeight];

This creates a 2D array dynamically, and we can access the pixels using notation
like pt[2, 3],
instead of the C++ pt[2][3]. Not only is this much neater than C++, but a Point[,] is a valid
parameter to pass into a function, making it a snap to pass around arrays of size unknown at
compile time.

Offset Filter
The first helper function we will write will take a relative location, so for example if we want to
move
pixel 2, 4 to location 5, 2, then pt[2, 4] will equal 3, -2. We could use Set/GetPixel to do this, but
we will continue to use direct access, which is probably faster. As we must now span an arbitrary
number of rows to access pixels from anywhere in the image, we will do so by using the Stride
member of the BitmapData, which we can multiply by our Y value to get the number of rows down.
Then our X value is multiplied by 3, because we are using 3 bytes per pixel ( 24 bit ) as our format.
The code looks like this:

Shrink ▲  

public static bool OffsetFilter(Bitmap b, Point[,] offset )

Bitmap bSrc = (Bitmap)b.Clone();

// GDI+ still lies to us - the return format is BGR, NOT RGB.

BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),

ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0,

bSrc.Width, bSrc.Height),

ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

int scanline = bmData.Stride;

System.IntPtr Scan0 = bmData.Scan0;

System.IntPtr SrcScan0 = bmSrc.Scan0;

unsafe

byte * p = (byte *)(void *)Scan0;

byte * pSrc = (byte *)(void *)SrcScan0;

int nOffset = bmData.Stride - b.Width*3;

int nWidth = b.Width;

int nHeight = b.Height;

int xOffset, yOffset;

for(int y=0;y < nHeight;++y)

for(int x=0; x < nWidth; ++x )

xOffset = offset[x,y].X;

yOffset = offset[x,y].Y;

p[0] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3)];

p[1] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 1];

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 3/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

p[2] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 2];

p += 3;

p += nOffset;

b.UnlockBits(bmData);

bSrc.UnlockBits(bmSrc);

return true;

You'll notice that the framework is there for a boolean success code, but it's not really used. The
OffsetFilterAbs does pretty much the same thing, except that if we want to move any pixel to
location 3, 2, the point stored for that location will be 3, 2 and not an offset. OffsetFilterAntiAlias is
much more complex because it implements a bilinear filter,
if you don't understand that code, refer
to the previous [^]article.

Now, the filters


The basic format then for all the filters is to create an array, populate it with values ( either offset or
absolute ) and then pass the bitmap and the array to the appropriate function. There is a lot of
trigonometry going on in quite a few of these, which I am not going to discuss in any great detail,
instead focusing on what the filter does, and it's parameters.

Flip
I guess the most obvious thing to do if we're going to move pixels around is flip the image.
I'll show
the code for this one as it is a simple example, which will highlight the underlying process more so
than later examples such as swirl. The end result is obvious, so I won't slow your bandwidth with an
example.

public static bool Flip(Bitmap b, bool bHorz, bool bVert)

Point [,] ptFlip = new Point[b.Width,b.Height];

int nWidth = b.Width;

int nHeight = b.Height;

for (int x = 0; x < nWidth; ++x)

for (int y = 0; y < nHeight; ++y)

ptFlip[x, y].X = (bHorz) ? nWidth - (x+1) : x;

ptFlip[x,y].Y = (bVert) ? nHeight - (y + 1) : y;

OffsetFilterAbs(b, ptFlip);

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 4/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

return true;

RandomJitter
This filter takes a number and moves each pixel by a random amount that is within the bounds of
that number. This is surprisingly effective, doing it multiple times ends up with quite an effective oil
painting effect.

Swirl
This filter was my personal holy grail, and the impetus for my coming up with this stuff. Basically it
starts in the middle, and moves around in a circle, increasing the radius as it also increases the
degree of rotation. As a result of using trig, it benefits greatly from the bilinear filter which is an
option. I will show both the normal,
then the bilinear filtered example for this image, then all others

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 5/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

that offer the filter, I will show with the filter on. The parameter that is passed in is a very small
number, for the example it is .05.

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 6/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Sphere
The sphere filter is one example of a filter created through playing around. I was trying for the effect
of
the image being wrapped around a ball. I don't think it works that well, but it is interesting and a
starting point for such an idea.

Time Warp
Another interesting filter, this one causes the image the warp as it disappears in the distance. The
example uses a factor of 15.

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 7/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Moire
While playing with the swirl idea, I discovered that if I increased the rate at which the radius moved
out, I could either get a wide swirl, or with the right parameters, a moire effect was produced. The
example uses a factor of 3.

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 8/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Water
A more useful filter is one that makes things appear to be underwater. This could be improved by
the addition of extra artifacts, such as rings and ripples. In effect this filter passes a sin wave through
the water in both x and y directions.

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 9/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Pixellate
This is an example of a filter which can be done generically but would be better done with specific
code. Pixellation is a way of referring to the fact that when an image is enlarged, curves become
blocky. This filter provides a mosaic effect by creating blocks that are the same colour as their top
left corner, and can also draw lines to mark the individual tiles. A better implementation would use
the average colour present within the block in question, as opposed to the top left corner, but this
still works quite well.

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 10/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Conclusion
https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 11/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

The filters provided are designed to show some of the things you can do with a displacement
framework, and to provide a variety of samples from which you can derive your own filters. I hope
you find the examples useful, and the framework a good starting point for your own explorations of
the underlying concept. I hope next to demonstrate writing of a specific one-off filter, and to
discuss how this is always the most flexible approach, although transformation matrices and
displacement techniques are an excellent way of establishing rough ideas and implementing
general concepts.

Updates
Version 1.01 : Added some bounds checking code in the three main filters so
that the filters do not
crash if any values passed in are out of bounds.
Some filters generate some out of bounds values on
the edges, and checking
this way causes more values to be processed than creating a border
around
all images.

This article is part of the series 'Image Processing for Dummies with C# and GDI+ ◁ Prev Next ▷

License
This article has no explicit license attached to it but may contain usage terms in the article text or
the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Written By

Christian Graus
Software Developer (Senior)
 Australia

Programming computers ( self taught ) since about 1984 when I bought my first Apple ][. Was
working on a GUI library to interface Win32 to Python, and writing graphics filters in my spare time,
and then building n-tiered apps using asp, atl and asp.net in my job at Dytech. After 4 years there,
I've started working from home, at first for Code Project and now for a vet telemedicine company. I
owned part of a company that sells client education software in the vet market, but we sold that
and I worked for the owners for five years before leaving to get away from the travel, and spend
more time with my family. I now work for a company here in Hobart, doing all sorts of Microsoft
based stuff in C++ and C#, with a lot of T-SQL in the mix.

Watch

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 12/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Comments and Discussions


 

Add a Comment or Question    Email Alerts Search Comments

First Prev Next

Preserve transparency of image


Member 13490304 28-Mar-20 14:43

My vote of 5
DrABELL 31-Aug-15 2:01

My vote of 5
Manoj Kumar Choubey 21-Feb-12 12:14

couldn't find web image processing in your blog


chandruvelan 15-Apr-11 17:03

Compiler Errors in Visual Studio 2010


vaxvax 21-Mar-11 3:29

Re: Compiler Errors in Visual Studio 2010


gluip 2-Feb-12 20:29

Cartoonist like filter


Glauber Torres 18-Nov-10 21:11

ECG wave extraction


biaali 11-Aug-10 15:19

Re: ECG wave extraction


Christian Graus 25-Aug-10 16:13

web cam image processing


behdad1985 17-Jan-10 17:08

Re: web cam image processing


Christian Graus 25-Aug-10 16:12

Image Pattern recognition using C#


Dan_danAUS 26-May-09 14:12

Christian can you help me understand how to make the Image Manipulation work in
asp.net.
Rob Gaudet 29-Jan-09 9:48

Thank you
futurejo 4-Jan-09 17:18

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 13/14
11/21/22, 9:59 PM Image Processing for Dummies with C# and GDI+ Part 5 - Displacement filters, including swirl - CodeProject

Detect Straight Lines and Show Co-ordinates of the line on the tiff
image(PixelFormat.Format1bppIndexed) using VB.net GDI
jeetu_1978 27-Dec-08 15:38

About Sphere!
Md. Arifuzzaman Roman 4-Dec-08 13:10

sort the images based on matching objects in them


patil.yogini.05 14-Nov-08 12:52

Converting a Bitmap To TIFF


ehsan_op 28-Sep-08 17:05

Re: Converting a Bitmap To TIFF


ckcool 27-May-09 11:08

Auto correction (brightness and contrast)


drkalucard 14-May-08 10:11

Invert Sphere Filter?


Scutter1337 18-Jan-08 7:32

Re: Invert Sphere Filter?


ersin38 6-Dec-08 23:14

Alpha woes
Unprofessional911 3-Oct-07 23:24

Re: Alpha woes


Christian Graus 4-Oct-07 3:41

Correcting red eyes


r_tebar 7-Apr-07 5:41

Refresh 1 2 3 4 5 6 7 8 9 10 11 Next ᐅ

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant   


Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink
Layout: fixed
|
fluid Article Copyright 2002 by Christian
Advertise
Graus

Privacy
Everything else
Copyright ©
Cookies
CodeProject, 1999-2022

Terms of Use

Web03 2.8:2022-11-08:1

https://www.codeproject.com/Articles/3419/Image-Processing-for-Dummies-with-C-and-GDI-Part-5 14/14

You might also like