图像特效---哈哈镜效果滤镜

时间:2022-09-10 22:22:26
哈哈镜效果滤镜 
    所谓哈哈镜,是一种表面凸凹不平的镜子,可以反应出人像及物件的扭曲面貌
    哈哈镜效果滤镜实际上是通过图像形变来模拟真实的哈哈镜效果。所谓形变是一系列的坐标变换,变换方法不同,呈现的效果也不同。本文将介绍如何通过三角变换公式来实现这个滤镜特效,具体算法过程如下:

  1,对于哈哈镜效果变换,首先它有两个参数,原点坐标和特效影响因子。

  对于图像中的像素点P(x,y),假设原点坐标为XY,那么,根据三角函数变换可以得到:

  当前像素P的相对坐标cX,cY:

    图像特效---哈哈镜效果滤镜

  3,由2中得到的新坐标就是像素P(x,y)的映射坐标,图像变换后的像素值就是映射坐标处的像素值。

  4,对于半径影响因子k,这里程序中设置为定值100,具体范围自己控制。

 以上就是哈哈镜的算法过程,同时我们放上核心代码如下:

        //

        ///

        /// Sunset Filter

        ///

        /// Source image.

        /// The X position of sun.

        /// The Y position of sun.

        /// The radius of sun light.

        /// The result image.

        private Bitmap ConvexFilterProcess(Bitmap srcBitmap, int cenX, int cenY, int radius)

        {

            Bitmap a = new Bitmap(srcBitmap);

            int w = a.Width;

            int h = a.Height;

            double distance = 0.0;

            double dis = 0.0;

            if (radius > cenX || radius > cenY)

            {

                radius = Math.Min(cenX, 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.Format24bppRgb);

            System.Drawing.Imaging.BitmapData dstData = dst.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            unsafe

            {

                byte* pIn = (byte*)srcData.Scan0.ToPointer();

                byte* pOut = (byte*)dstData.Scan0.ToPointer();

                byte* p = (byte*)srcData.Scan0.ToPointer();

                int sWidth = srcData.Stride;

                int stride = sWidth - w * 3;

                int R, G, B;

                int newX = 0, newY = 0;

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

                {

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

                    {

                        B = pIn[0];

                        G = pIn[1];

                        R = pIn[2];

                        distance = (x - cenX) * (x - cenX) + (y - cenY) * (y - cenY);

                        dis = Math.Sqrt(distance);

                        if (distance <= radius * radius && distance > 0)

                        {

                            newX = (int)(Math.Floor(dis * (double)(x - cenX) / (double)radius + (double)cenX)+0.5);

                            newY = (int)(Math.Floor(dis * (double)(y - cenY) / (double)radius + (double)cenY)+0.5);

                            pOut[0] = (byte)(*(p + newX * 3 + newY * srcData.Stride));

                            pOut[1] = (byte)(*(p + newX * 3 + 1 + newY * srcData.Stride));

                            pOut[2] = (byte)(*(p + newX * 3 + 2 + newY * srcData.Stride));

                        }

                        else

                        {

                            pOut[0] = (byte)B;

                            pOut[1] = (byte)G;

                            pOut[2] = (byte)R;

                        }

                        pIn += 3;

                        pOut += 3;

                    }

                    pIn += stride;

                    pOut += stride;

                }

                a.UnlockBits(srcData);

                dst.UnlockBits(dstData);

            }

            return dst;


        }

  哈哈镜效果如下:

图像特效---哈哈镜效果滤镜

原图

图像特效---哈哈镜效果滤镜

哈哈镜效果图


程序demo: http://www.zealfilter.com/forum.php?mod=viewthread&tid=53&extra=page%3D2