原文:图像滤镜艺术---球面(Spherize)滤镜

球面(Spherize)滤镜

球面滤镜是通过极坐标变换实现图像的球面特效。

代码如下:

        //

        ///

        /// Pinch Filter

        ///        /// Source image.

        /// The X position of sun.

        /// The Y position of sun.

        /// The result image.

        private Bitmap SpherizeFilterProcess(Bitmap srcBitmap, int cenX, int cenY)

        {

            Bitmap a = new Bitmap(srcBitmap);

            int w = a.Width;

            int h = a.Height;

            int radius = 0;

            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 sWidth = srcData.Stride;

                int stride = sWidth - w * 4;

                int offsetX = 0, offsetY = 0;

                int newX = 0, newY = 0;

                double radian = 0;

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

                {

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

                    {

                        offsetX = x - cenX;

                        offsetY = y - cenY;

                        radian = Math.Atan2(offsetY, offsetX);

                        radius = (int)((offsetX * offsetX + offsetY * offsetY) / Math.Max(cenX, cenY));

                        newX = (int)(radius * Math.Cos(radian)) + cenX;

                        newY = (int)(radius * Math.Sin(radian)) + 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;

                        pOut[0] = (byte)p[0];

                        pOut[1] = (byte)p[1];

                        pOut[2] = (byte)p[2];

                        pOut[3] = (byte)255;                     

                        pOut += 4;

                    }

                    pOut += stride;

                }

                a.UnlockBits(srcData);

                dst.UnlockBits(dstData);

            }

            return dst;

        }

效果图如下:

原图

效果图(X=240,Y=240)

最后放上一个完整的C#板程序DEMO:http://www.zealpixel.com/forum.php?mod=viewthread&tid=56&extra=page%3D1

最新文章

  1. snakebar 的使用
  2. mysql5.6新特性总结
  3. 答:SQLServer DBA 三十问之一: char、varchar、nvarchar之间的区别(包括用途和空间占用);xml类型查找某个节点的数据有哪些方法,哪个效率高;使用存储 过程和使用T-SQL查询数据有啥不一样;
  4. SQL Server之游标的基础知识
  5. Java学习-039-源码 jar 包的二次开发扩展实例(源码修改)
  6. MySQL SQL
  7. glibc 简介:
  8. Swift学习笔记
  9. NOIP200505谁拿了最多的奖学金
  10. 比较常见的const与指针的组合情况
  11. GitLab一键式安装bitnami
  12. iOS开发中UIPopoverController的使用详解
  13. mac 配置jdk,maven环境变量
  14. webpack常见的配置项
  15. class用法
  16. how to tell gcc with c99 enable
  17. 无法给MySQL root用户修改密码的解决方法
  18. [JS] ECMAScript 6 - Set &amp; Map : compare with c#
  19. [Web 前端 ] 五大WEB主流浏览器及四大内核
  20. POJ2311 Cutting Game

热门文章

  1. 【74.89%】【codeforces 551A】GukiZ and Contest
  2. [Ramda] Declaratively Map Data Transformations to Object Properties Using Ramda evolve
  3. SQLServer重建索引
  4. 如何安全退出多个Activity
  5. Redis的增删改查、持久化你会了吗
  6. Windows下启动ActiveMq端口被占用的解决办法
  7. 学习鸟哥的Linux私房菜笔记(13)——用户管理
  8. noip刷题记录 20170823
  9. 华为云软件开发云:容器DevOps,原来如此简单!
  10. Spring实战5-基于Spring构建Web应用