Hi Lloyd,
I don't know if you could use DirectX to do this, but it can be done with
the System.Drawing and System.Drawing.Imaging namespaces alone, if you use
some unsafe C code in your app. Example:
public static bool Smooth(Bitmap b)
{
ConvMatrix m = new ConvMatrix(0);
SetAll(ref m, 1);
m.Pixel = 4;
m.Factor = 12;
return Conv3x3(b, m);
}
public static bool Conv3x3(Bitmap b, ConvMatrix m)
{
// Avoid divide by zero errors
if (0 == m.Factor) return false;
Bitmap bSrc = (Bitmap)b.Clone();
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 stride = bmData.Stride;
int stride2 = stride * 2;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
byte * pSrc = (byte *)(void *)SrcScan0;
int nOffset = stride - b.Width*3;
int nWidth = b.Width - 2;
int nHeight = b.Height - 2;
int nPixel;
for(int y=0;y < nHeight;++y)
{
for(int x=0; x < nWidth; ++x )
{
nPixel = ( ( ( (pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8]
* m.TopRight) +
(pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) +
(pSrc[8 + stride] * m.MidRight) +
(pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid)
+ (pSrc[8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[5 + stride]= (byte)nPixel;
nPixel = ( ( ( (pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7]
* m.TopRight) +
(pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) +
(pSrc[7 + stride] * m.MidRight) +
(pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid)
+ (pSrc[7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[4 + stride] = (byte)nPixel;
nPixel = ( ( ( (pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6]
* m.TopRight) +
(pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) +
(pSrc[6 + stride] * m.MidRight) +
(pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid)
+ (pSrc[6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[3 + stride] = (byte)nPixel;
p += 3;
pSrc += 3;
}
p += nOffset;
pSrc += nOffset;
}
}
b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);
return true;
}
public struct ConvMatrix
{
public int TopLeft, TopMid, TopRight;
public int MidLeft, Pixel, MidRight;
public int BottomLeft, BottomMid, BottomRight;
public int Factor;
public int Offset;
public ConvMatrix(int intOffSet)
{
TopLeft = 0;
TopMid = 0;
TopRight = 0;
MidLeft = 0;
Pixel = 1;
MidRight = 0;
BottomLeft = 0;
BottomMid = 0;
BottomRight = 0;
Factor = 1;
Offset = intOffSet;
}
}
--
HTH,
Kevin Spencer
Microsoft MVP
.Net Developer
Big things are made up of
lots of little things.
Lloyd Dupont said:
In our WinForm / C# application relying on C# 2.0 I have a big canvas
with shapes on it.
I would like to display shadow (monochrome gaussian blur) with arbitrary
offset & dispersion radius under my shapes.
I try to draw to a bitmap and apply a plur filter myself on each bitmap
(for each shape), but it's awfully slow.
I was wondering if:
1. could DirectX be used to do the blur operation quickly?
2. would DirectX.NET be included in the 2.0 distribution or should I, as
with 1.1, download/install an additional package? how big it is?
--
Regards,
Lloyd Dupont
NovaMind development team
NovaMind Software
Mind Mapping Software
<
www.nova-mind.com>