Well it's not going to be particularly hard, though it will take more than 2 seconds.
The basic steps you need are.
1. Make bitmap of screen underneath window
2. Blur this bitmap
3. Desaturate the image
4. Colorize the image
5. Create a new bitmap, the size of your window
6. Fill with a solid colour
7. Using the image from step#4 as a brush & some regions, copy to bitmap from step5
8. draw client area etc into bitmap from step5
9. Throw the thing onto the screen.
Here's a function that will do the blurring for you. You should call it with a convolution filter.
I forget now, though I seem to remember that the function may only work on images created with CreateDIBSection - any other image type and the app crashes.
As for the desaturation and colourizing - you'll need to work in either the HSV or HSL colorspace to do that - RGB just isn't suited to perceptual changes like the ones you need here.
Examples:
double BlurFilter1[] =
{
0, 1, 1, 1, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
0, 1, 1, 1, 0,
}; factor = 1.0/21.0; bias = 0.0;
filterBitmap(target, BlurFilter1, 5, 5, 1.0/21.0);
double BlurFilter2[] =
{
0, 1, 0,
1, 1, 1,
0, 1, 0,
}; factor = 1.0/5.0; bias = 0.0;
filterBitmap(target, BlurFilter2, 3, 3, 1.0/5.0);
double motionBlurFilter1[] =
{
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
0, 0, 0, 0, 1,
}; factor = 1.0/5.0; bias = 0.0;
filterBitmap(target, motionBlurFilter1, 5, 5, 1.0/5.0);
double motionBlurFilter2[] =
{
1, 1, 1, 1, 1,
} factor = 1.0/5.0; bias = 0.0;
filterBitmap(target, motionBlurFilter2, 5, 1, 1.0/5.0);
/ vertical medium motion blur
double motionBlurFilter3[] =
{
1,
1,
1,
1,
1,
} factor = 1.0/5.0; bias = 0.0;
filterBitmap(target, motionBlurFilter3, 1, 5, 1.0/5.0);
double darkenFilter[] =
{
1,
} factor = 0.9/1.0; bias = 0.0;
filterBitmap(target, darkenFilter, 1, 1, 0.9/1.0);
void filterBitmap(HBITMAP target, double *filter, int filterWidth, int filterHeight, double factor, double bias=0.0)
{
HBITMAP resultBmp;
BITMAP bmInfo;
int x, y, filterX, filterY;
int bmpWidth, bmpHeight;
unsigned char *srcImage, *dstImage;
int bytesPerRow;
HDC srcDC, destDC;
HBITMAP bm1, bm2;
int i;
GetObject(target, sizeof(bmInfo), &bmInfo);
bmpWidth = bmInfo.bmWidth;
bmpHeight = bmInfo.bmHeight;
srcImage = (unsigned char*)bmInfo.bmBits;
bytesPerRow = bmpWidth;
bytesPerRow *= 3;
if (bytesPerRow %2)
bytesPerRow ++;
resultBmp = CreateCompatibleBitmap(GetDC(0), bmpWidth, bmpHeight);
GetObject(target, sizeof(bmInfo), &bmInfo);
dstImage = (unsigned char*)bmInfo.bmBits;
srcDC = CreateCompatibleDC(GetDC(0));
destDC = CreateCompatibleDC(GetDC(0));
bm1 = (HBITMAP)SelectObject(srcDC, target);
bm2 = (HBITMAP)SelectObject(destDC, resultBmp);
for (x=0; x<bmpWidth; x++)
for (y=0; y<<bmpheight;y++)
{
double red=0.0, green=0.0, blue=0.0;
for(filterX = 0; filterX < filterWidth; filterX++)
for(filterY = 0; filterY < filterHeight; filterY++)
{
int imageX = (x - filterWidth / 2 + filterX + bmpWidth) % bmpWidth;
int imageY = (y - filterHeight / 2 + filterY + bmpHeight) % bmpHeight;
red += srcImage[imageX*3 + bytesPerRow*imageY + 2] * filter[filterX +filterWidth*filterY];
green += srcImage[imageX*3 + bytesPerRow*imageY + 1] * filter[filterX + filterWidth*filterY];
blue += srcImage[imageX*3 + bytesPerRow*imageY + 0] * filter[filterX + filterWidth*filterY];
}
dstImage[x*3 + bytesPerRow*y + 2] = min(max((int)(factor * red + bias), 0), 255);
dstImage[x*3 + bytesPerRow*y + 1] = min(max((int)(factor * green + bias), 0), 255);
dstImage[x*3 + bytesPerRow*y + 0] = min(max((int)(factor * blue + bias), 0), 255);
}
BitBlt(destDC, 0,0, bmpWidth, bmpHeight, srcDC, 0, 0, SRCCOPY);
DeleteObject(resultBmp);
SelectObject(srcDC, bm1);
SelectObject(destDC, bm2);
DeleteDC(srcDC);
DeleteDC(destDC);
}
|