# The Dancing Pixels, or the Pixels in Water

### WEBINAR:On-Demand

Application Security Testing: An Integral Part of DevOps

Environment: Visual C++

To start with, the program is a small-time animation in VC++. What does an image look like when it is dipped in a tub of water when the tub is subjected to a constant vibration? The more difficult part is to produce the ripple effect, as when a pebble is thrown in the tub. So, I will tell at least this much.

The difference I make is that I am going to explain how to produce this effect, not simply copy and paste code form somewhere. Much of the code that I saw over the Net regarding small-time animation carries no explanation at all.

### Some Theory

Let p(x,y) be a pixel at the x,y coordinate in an image. Imagine the pixel p(x,y) moving randomly around its four m-neighbourhoods, namely p(x-m,y-m),p(x+m,y+m), p(x-m,y),p(x,y-m) randomly, where m is a natural number {1,2,3,4,5,6,...}. Think what will happen if all the pixels in the image move in such a manner; you get the effect.

### The Practice

When someone clicks the Ok button, I do the following:

```CDC me1;
CBitmap ma1;
BITMAP info1;

CDC me3;
CBitmap ma3;
BITMAP info3;
```

All the above all globals.

```ma1.LoadBitmap(IDB_BITMAP1);
me1.CreateCompatibleDC(dc);
ma1.GetBitmap(&info1);
me1.SelectObject(ma1);

me3.CreateCompatibleDC(dc);
ma3.CreateCompatibleBitmap(dc,1000,1000);
me3.SelectObject(ma3);
me3.BitBlt(0,0,1000,1000,dc,0,0,SRCCOPY);
```

I have one more copy of the DC just in case you need it for more animation tricks; it is not required here, though.

```me3.BitBlt(0,0,info1.bmWidth,info1.bmHeight,&me1,0,0,SRCCOPY);

HBITMAP hbm=NULL;

HDC DeskHdc=::GetDC(NULL);
HDC hdc=::CreateCompatibleDC(DeskHdc);

& ~31) >> 3) * info1.bmHeight;
BitmapInfo.bmiHeader.biClrUsed  = 0;    // we are not using palette
BitmapInfo.bmiHeader.biPlanes   = 1;    // has to be 1
BitmapInfo.bmiHeader.biBitCount = 32;   // as we want true-color

hbm=::CreateDIBSection(GetDesktopWindow()->GetWindowDC()
->m_hDC,
&BitmapInfo,DIB_RGB_COLORS,(void**)&imageData,NULL,0);
HBITMAP m_hbmOld;

if (hbm)
{
m_hbmOld = (HBITMAP)::SelectObject(hdc,hbm);
}

::BitBlt(hdc,0,0,info1.bmWidth,info1.bmHeight,me3.m_hDC,0,0,
SRCCOPY);
```

The above is a standard piece of code that would be given in any good VC++ books.

It is done so that I get access to the image's bits that are now in the imageData member; the trick is to manipulate the bits directly and use SetDIBitsToDevice(--) to plot the image quickly and finally to repeat the process in a timer.

So, let us look at the OnTimer function: When we enter the timer for the first time, I want to copy the image bits array into another pointer, namely p, and a two-dimensional array, namely imgArr.

```if(r= =0)
{
for(intj=0;j<=info1.bmHeight;j++)
for(intk=0;k<=info1.bmWidth;k++)
{
imgArr[j][k]=p[j*info1.bmWidth+k]; // See note below for this
// calculation
}
r= 1;
}
```

I want to stop this timer until I finish the following processing:

`KillTimer(0);`

Run through the whole image:

```for(intk=0;k<=info1.bmHeight;k++)
for(intf=0;f<=info1.bmWidth;f++)
{
int R,G,B;
int Rx,Gx;

//Rx=rand()%(int)m+k;
//Gx=rand()%(int)m+f;
```

Then, I pick up a random 3-neighbouring pixel from the place (k,f):

```Rx=rand()%(int)3+k;
Gx=rand()%(int)3+f;
```

Put the current pixel (the k,f guy) = the so-selected 3-neighbouring pixel:

```p[k*info1.bmWidth+f]=imgArr[Rx][Gx];    // For more explanation
// of this calculation,
// see the note at the end
}
```

Now, all the pixels in the image have been replaced by their 3-neighbouring guys, that too randomly:

```m-=.5;
if(m<1)
m=20;
if(r>info1.bmWidth)
r=0;
SetDIBitsToDevice(::GetDC(NULL),
0,
0,
info1.bmWidth,
info1.bmHeight,
0,
0,
0,
info1.bmHeight,
p,
//imageData,
&BitmapInfo,
DIB_RGB_COLORS);
```

Now, resume the timer for the next round of random replacement:

`SetTimer(0,30,0);`
Note: One item worth mentioning will be how the bits are stored in one single array. From p[0] to p[info1.bmWidth], we have a single row of the image, then from p[info1.bmWidth+1] to p[info1.bmWidth+ info1.bmWidth] is the second row of the image and so on until p[info1.bmWidth*info1.bmHeight].

• #### thanks

Posted by chinesoul on 04/18/2007 02:05pm

As a beginner, this code helps me a lot.

• You must have javascript enabled in order to post comments.

## Top White Papers and Webcasts

• As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
• The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
• Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

## Most Popular Programming Stories

• There have been no articles posted today.