图像特效---旋转模糊滤镜

来源:互联网 发布:mac怎么打开rar 编辑:程序博客网 时间:2024/04/30 15:24
本文介绍一种旋转模糊滤镜的实现算法。
旋转模糊主要特点是:整张图像围绕一个中心点做旋转变换,同时有个控制旋转程度的变量和一个控制模糊程度的变量,来完成这个效果。图像中距离中心点越近,旋转和模糊的程度都越小,反之,越大。
假设中心点O坐标为(cenX,cenY),当前点位置为P(x,y):
1,PO距离Dis=Math.Sqrt((y - cenY) * (y - cenY) + (x - cenX) * (x - cenX));
2,PO和水平方向夹角angle=Math.Atan2((double)(y - cenY), (double)(x - cenX));
3,当前点P对应的旋转后新的坐标newX,newY计算:
newX = Dis * Math.Cos(angle) + cenX;
newY = Dis * Math.Sin(angle) + cenY;
下面给出完整的C#代码:
 ///
        /// Rotate Blur
        ///
        /// Source image.
        /// The X position of Blur.
        /// The Y position of Blur.
        /// The intensity of blur,0-100.
        /// The result image.
        private Bitmap RotateBlurProcess(Bitmap srcBitmap, int cenX, int cenY, int intensity)
        {
            Bitmap a = new Bitmap(srcBitmap);
            int w = a.Width;
            int h = a.Height;
            cenX = Math.Min(w - 1, Math.Max(0, cenX));
            cenY = Math.Min(h - 1, Math.Max(0, cenY));
            Bitmap dst = new Bitmap(w, h);
            System.Drawing.Imaging.BitmapData srcData = a.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            System.Drawing.Imaging.BitmapData dstData = dst.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            unsafe
            {
                byte* pIn = (byte*)srcData.Scan0.ToPointer();
                byte* pOut = (byte*)dstData.Scan0.ToPointer();
                byte* p = null;
                int stride = srcData.Stride - w * 4;
                int newX = 0, newY = 0;
                double angle = 0;
                double temp = 0, r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        r = 0;
                        g = 0;
                        b = 0;
                        temp = Math.Sqrt((y - cenY) * (y - cenY) + (x - cenX) * (x - cenX));
                        angle = Math.Atan2((double)(y - cenY), (double)(x - cenX));
                        for (int n = 0; n < intensity; n++)
                        {
                            angle = angle + 0.005;
                            newX = (int)(temp * Math.Cos(angle) + (double)cenX);
                            newY = (int)(temp * Math.Sin(angle) + (double)cenY);
                            newX = Math.Min(w - 1, Math.Max(0, newX));
                            newY = Math.Min(h - 1, Math.Max(0, newY));
                            p = pIn + newY * srcData.Stride + newX * 4;
                            b = b + p[0];
                            g = g + p[1];
                            r = r + p[2];
                        }
                        b = Math.Min(255, Math.Max(0, b / intensity));
                        g = Math.Min(255, Math.Max(0, g / intensity));
                        r = Math.Min(255, Math.Max(0, r / intensity));
                        pOut[0] = (byte)b;
                        pOut[1] = (byte)g;
                        pOut[2] = (byte)r;
                        pOut[3] = (byte)255;
                        pOut += 4;
                    }
                    pOut += stride;
                }
                a.UnlockBits(srcData);
                dst.UnlockBits(dstData);
            }
            return dst;
        }
最后,看下效果图:

原图

效果图

demo link: 点击打开链接
0 0
原创粉丝点击