using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;

namespace myControl
{
    public struct DropData
    {
        public int x;
        public int y;
        public int radius;
        public int height;
    }

    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);

            Timer myWaterTimer = new Timer();
            myWaterTimer.Interval = ;
            myWaterTimer.Tick += new EventHandler(myWaterTimer_Tick);
            Timer myDropsTimer = new Timer();
            myDropsTimer.Interval = ;
            myDropsTimer.Tick += new EventHandler(myDropsTimer_Tick);
        }

        private void myDropsTimer_Tick(object sender, EventArgs e)
        {
            try
            {

                this.myDropsTimer.Enabled = false;
                int _percent = (int)(0.005 * (this.Width + this.Height));
                int _dropsNumber = r.Next(_percent);
                ;
                ; i < _dropsNumber; i++)
                {
                    _drop = r.Next(drops.Length);
                    DropWater(drops[_drop].x, drops[_drop].y, drops[_drop].radius, drops[_drop].height);
                }

                 * _percent) + ;
                this.myDropsTimer.Enabled = true;
            }
            catch { }
        }

        private void myWaterTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                if (fastImage.IsLocked()) return;
                this.myWaterTimer.Stop();
                PaintWater();
                this.myWaterTimer.Start();
            }
            catch { }
        }

        ;
        ;
        ;
        private static DropData[] drops;
        private FastBitmap fastImage = null;
        private FastBitmap originalImage = null;
        ;
        ;
        private byte[] bitmapOriginalBytes;
        private Random r = new Random();
        private static int[][][] waveHeight;
        bool isLoaded = false;

        private Image image;
        private bool auto;
        private int number;

        private Timer myWaterTimer, myDropsTimer;

        /// <summary>
        /// 绘画的图片
        /// </summary>
        public Image Image
        {
            get { return image; }
            set { image = value; }
        }
        /// <summary>
        /// 自动产生
        /// </summary>
        public bool Auto
        {
            get { return auto; }
            set { auto = value; }
        }
        /// <summary>
        /// 源点数
        /// </summary>
        public int Number
        {
            get { return number; }
            set { number = value; }
        }

        public void load()
        {
            try
            {
                isLoaded = true;
                this.Width = image.Width;
                this.Height = image.Height;
                bitmapWidth = image.Width;
                bitmapHeight = image.Height;
                waveHeight = new int[bitmapWidth][][];
                ; i < bitmapWidth; i++)
                {
                    waveHeight[i] = new int[bitmapHeight][];
                    ; j < bitmapHeight; j++)
                    {
                        waveHeight[i][j] = ];
                    }
                }
                CreateBitmap();
                if (auto)
                {
                    CreateWaterDrops();
                    this.myWaterTimer.Enabled = true;
                    ;
                    this.myDropsTimer.Enabled = true;
                }
                else
                {
                    this.MouseMove += new MouseEventHandler(myWaterWave_MouseMove);
                }
            }
            catch { }

        }

        private void CreateBitmap()
        {
            originalImage = new FastBitmap((Bitmap)(image).Clone(), bits);
            originalImage.LockBits();
            fastImage = new FastBitmap((Bitmap)(image).Clone(), bits);
            bitmapOriginalBytes = new byte[bits * fastImage.Width() * fastImage.Height()];
            fastImage.LockBits();
            Marshal.Copy(fastImage.Data().Scan0, bitmapOriginalBytes, , bitmapOriginalBytes.Length);
            fastImage.Release();
        }

        private void DropWater(int x, int y, int radius, int height)
        {
            long _distance;
            int _x;
            int _y;
            Single _ratio;
            _ratio = (Single)((Math.PI / (Single)radius));

            for (int i = -radius; i <= radius; i++)
            {
                for (int j = -radius; j <= radius; j++)
                {
                    _x = x + i;
                    _y = y + j;
                    ) && (_x <= bitmapWidth - ) && (_y >= ) && (_y <= bitmapHeight - ))
                    {
                        _distance = (long)Math.Sqrt(i * i + j * j);
                        if (_distance <= radius)
                        {
                            waveHeight[_x][_y][currentHeightBuffer] = (int)(height * Math.Cos((Single)_distance * _ratio));
                        }
                    }
                }
            }
        }

        private void PaintWater()
        {
            newHeightBuffer = (currentHeightBuffer + ) % ;
            fastImage.LockBits();
            byte[] _bufferBits = new byte[bits * fastImage.Width() * fastImage.Height()];
            Marshal.Copy(fastImage.Data().Scan0, _bufferBits, , _bufferBits.Length);
            int _offX;
            int _offY;
            ; _x < bitmapWidth - ; _x++)
            {
                ; _y < bitmapHeight - ; _y++)
                {
                    unchecked
                    {
                        waveHeight[_x][_y][newHeightBuffer] = ((
                            waveHeight[_x - ][_y][currentHeightBuffer] +
                            waveHeight[_x - ][_y - ][currentHeightBuffer] +
                            waveHeight[_x][_y - ][currentHeightBuffer] +
                            waveHeight[_x + ][_y - ][currentHeightBuffer] +
                            waveHeight[_x + ][_y][currentHeightBuffer] +
                            waveHeight[_x + ][_y + ][currentHeightBuffer] +
                            waveHeight[_x][_y + ][currentHeightBuffer] +
                            waveHeight[_x - ][_y + ][currentHeightBuffer]) >> )
                        - waveHeight[_x][_y][newHeightBuffer];
                    }
                    waveHeight[_x][_y][newHeightBuffer] -= (waveHeight[_x][_y][newHeightBuffer] >> );
                    _offX = ((waveHeight[_x - ][_y][newHeightBuffer] - waveHeight[_x + ][_y][newHeightBuffer])) >> ;
                    _offY = ((waveHeight[_x][_y - ][newHeightBuffer] - waveHeight[_x][_y + ][newHeightBuffer])) >> ;
                    ) && (_offY == )) continue;
                    ) _offX = -_x;
                    ) _offX = bitmapWidth - _x - ;
                    ) _offY = -_y;
                    ) _offY = bitmapHeight - _y - ;
                    _bufferBits[bits * (_x + _y * bitmapWidth) + ] = bitmapOriginalBytes[bits * (_x + _offX + (_y + _offY) * bitmapWidth) + ];
                    _bufferBits[bits * (_x + _y * bitmapWidth) + ] = bitmapOriginalBytes[bits * (_x + _offX + (_y + _offY) * bitmapWidth) + ];
                    _bufferBits[bits * (_x + _y * bitmapWidth) + ] = bitmapOriginalBytes[bits * (_x + _offX + (_y + _offY) * bitmapWidth) + ];
                }
            }
            Marshal.Copy(_bufferBits, , fastImage.Data().Scan0, _bufferBits.Length);
            currentHeightBuffer = newHeightBuffer;
            this.Invalidate();
        }

        private void CreateWaterDrops()
        {
            int _dropX;
            int _dropY;
            int _dropRadius;
            int _height;

            int _percent = (int)(0.0015 * (this.Width + this.Height));
            drops = new DropData[number];

            ; i < drops.Length; i++)
            {
                _dropX = r.Next(bitmapWidth);
                _dropY = r.Next(bitmapHeight);
                _height = r.Next();
                _dropRadius = r.Next( * _percent);

                ) _dropRadius = ;

                drops[i].x = _dropX;
                drops[i].y = _dropY;
                drops[i].radius = _dropRadius;
                drops[i].height = _height;
            }
        }

        private void myWaterWave_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                if (isLoaded)
                {
                    fastImage.Release();
                    e.Graphics.DrawImage(fastImage.Bitmap, , , fastImage.Width(), fastImage.Height());
                }
            }
            catch { }
        }

        private void myWaterWave_MouseMove(object sender, MouseEventArgs e)
        {
            int dropX;
            int dropY;
            int dropRadius;
            int height;
            int percent = (int)(0.0015 * (this.Width + this.Height));
            drops = ];
            dropX = e.X;
            dropY = e.Y;
            height = r.Next();
            dropRadius = r.Next( * percent);

            ) dropRadius = ;

            drops[].x = dropX;
            drops[].y = dropY;
            drops[].radius = dropRadius;
            drops[].height = height;
            this.myWaterTimer.Enabled = true;
            ;
            this.myDropsTimer.Enabled = true;
        }
        private void Form1_MouseLeave(object sender, EventArgs e)
        {
          this.myDropsTimer.Enabled = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }

    public unsafe class FastBitmap
    {

        public struct PixelData
        {
            public byte blue;
            public byte green;
            public byte red;
            public byte alpha;
        }

        Bitmap Subject;
        int SubjectWidth;
        BitmapData bitmapData = null;
        Byte* pBase = null;
        bool isLocked = false;
        ;

        public FastBitmap(Bitmap SubjectBitmap, int bits)
        {
            this.Subject = SubjectBitmap;
            _bits = bits;
            try
            {
                //LockBits();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Release()
        {
            try
            {
                UnlockBits();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Bitmap Bitmap
        {
            get
            {
                return Subject;
            }
        }

        public void SetPixel(int X, int Y, Color Colour)
        {
            try
            {
                PixelData* p = PixelAt(X, Y);
                p->red = Colour.R;
                p->green = Colour.G;
                p->blue = Colour.B;
            }
            catch (AccessViolationException ave)
            {
                throw (ave);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public Color GetPixel(int X, int Y)
        {
            try
            {
                PixelData* p = PixelAt(X, Y);
                return Color.FromArgb((int)p->red, (int)p->green, (int)p->blue);
            }
            catch (AccessViolationException ave)
            {
                throw (ave);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public int Width() { return Subject.Width; }
        public int Height() { return Subject.Height; }
        public bool IsLocked() { return isLocked; }
        public BitmapData Data() { return bitmapData; }

        public void LockBits()
        {
            if (isLocked) return;
            try
            {
                GraphicsUnit unit = GraphicsUnit.Pixel;
                RectangleF boundsF = Subject.GetBounds(ref unit);
                Rectangle bounds = new Rectangle((int)boundsF.X,
                    (int)boundsF.Y,
                    (int)boundsF.Width,
                    (int)boundsF.Height);

                SubjectWidth = (int)boundsF.Width * sizeof(PixelData);
                )
                {
                    SubjectWidth = _bits * (SubjectWidth / _bits + );
                }
                )
                    bitmapData = Subject.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                else
                    bitmapData = Subject.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
                pBase = (Byte*)bitmapData.Scan0.ToPointer();
            }
            finally
            {
                isLocked = true;
            }
        }

        private PixelData* PixelAt(int x, int y)
        {
            return (PixelData*)(pBase + y * SubjectWidth + x * sizeof(PixelData));
        }

        private void UnlockBits()
        {
            if (bitmapData == null) return;
            Subject.UnlockBits(bitmapData);
            bitmapData = null;
            pBase = null;
            isLocked = false;
        }
    }
}

c# 图片带水纹波动的更多相关文章

  1. canvas实现点击带水纹的按钮

    咱今天在闲逛网页时,看到一个点击带水纹的按钮特效,尼玛,写的还挺好,先看效果: 于是就奔着升级版的拿来主义,别人的好东西,咱都要拿来滴,so,扒代码! 完整代码在最后,是经过我的改进优化滴. 在这里先 ...

  2. 有趣的css3实战案例剖析——(水纹波动)

    对于css3的学习,更多的是在于对新特性和基础理论的熟悉, 这篇文章通过一个案例带领大家了解css3里一些理论知识,也将一些技巧加以总结,从而提高大家的开发效率: 本次案例为(水纹波动),不用js写动 ...

  3. Qrcode生成二维码支持中文,带图片,带文字

    1.下载Qrcode库源码, 下载地址:http://www.codeproject.com/Articles/20574/Open-Source-QRCode-Library2.打开源码时, 部分类 ...

  4. Excel催化剂开源第9波-VSTO开发图片插入功能,图片带事件

    图片插入功能,这个是Excel插件的一大刚需,但目前在VBA接口里开发,如果用Shapes.AddPicture方法插入的图片,没法对其添加事件,且图片插入后需等比例调整纵横比例特别麻烦,特别是对于插 ...

  5. (转载)图片左右滚动控件(带倒影)——重写Gallery

    今天在网上找了些资料,做了一个图片左右滚动的Demo,类似幻灯片播放,同时,图片带倒影效果,运行效果如下图: 实现方式是重写Gallery,使用自定义的Gallery来实现这一效果,工程一共三个文件, ...

  6. 图片左右滚动控件(带倒影)——重写Gallery

    转http://blog.csdn.net/ryantang03/article/details/8053643 今天在网上找了些资料,做了一个图片左右滚动的Demo,类似幻灯片播放,同时,图片带倒影 ...

  7. 第三方的图片加载( Android-Universal-Image-Loader)

    Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示. (1).使用多线程加载图片(2).灵活配置Im ...

  8. 想在BD自然排名中脱颖而出吗?加张合适的图片吧!

    经常在BD或gg搜索不难发现有些搜索结果会带有缩略图,类似下图,图文搭配,看着不累 在一大排搜索结果中,都是文字的话,还没认真看就感觉累,如果在这些搜索结果中突然出现一条图文结合的条目,是不是有耳目一 ...

  9. 30款jQuery常用网页焦点图banner图片切换 下载

    1.jquery 图片滚动特效制作 slide 图片类似窗帘式图片滚动 查看演示 2.jquery幻灯片插件带滚动条的圆形立体图片旋转滚动 查看演示 3.jQuery图片层叠旋转类似洗牌翻转图片幻灯片 ...

随机推荐

  1. docker容器下mysql更改WordPress的site address和home(URL)------局域网

    先简单介绍下,用docker安装的WordPress,mysql是在docker容器中的,并未在Ubuntu(我把WordPress是安装Ubuntu系统上),即WordPress和Ubuntu是独立 ...

  2. 《HTTP权威指南》2-URL

    前言 在一个城市中,所有的东西都有一个标准化的名字,以帮助人们寻找城市中的各种资源,如宁波火车站地铁站,在因特网这座大城市中,URL就是其标准化名称,它指向每一条电子信息,告诉你它们位于何处,以及如何 ...

  3. linux系统下安装redis以及java调用redis

    关系型数据库:MySQL  Oracle 非关系型数据库:Redis 去掉主外键等关系数据库的关系性特性 1)安装redis编译的c环境,yum install gcc-c++ 2)将redis-2. ...

  4. CLion之C++框架篇-优化框架,引入boost(三)

      背景   结合上一篇CLion之C++框架篇-优化框架,单元测试(二),继续进行框架优化!这一版优化引入一个我们日常经常使用的操作库Boost,估算使用频率在70%以上!   Boost的优势在哪 ...

  5. Microsoft Azure IoTHub Serials 2 - 如何为android应用添加IoTHub支持

    1. 在build.gradle(app)文件的dependencies中添加对以下项的依赖: 'com.microsoft.azure.sdk.iot:iot-device-client:1.5.3 ...

  6. Android优化指南

    Android系统中GC内存泄漏的原因 主动回收内存System.gc();.getruntime.runtime.gc 导致内存泄漏主要的原因是,申请了内存空间而忘记了释放.如果程序中存在对无用对象 ...

  7. 第34节:Java当中的异常

    Java当中的异常 了解Java当中的异常,那么什么是异常呢?异常又有什么分类呢?异常中的特殊结构:try...catch...finally 结构的使用方法. 异常是一种对象,是靠虚拟机产生的,异常 ...

  8. SpringBoot整合Mybatis完整版

    喜欢的朋友可以关注下,粉丝也缺. 自从Spring推出Boot,Cloud系列之后,一度成为热门的框架,现在大部分的招聘要求都要有相关的开发经验,借此我在这里就给大家分享一下如何玩转SpringBoo ...

  9. MacOS下命令行安装神器brew

    1.安装brew:/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/mast ...

  10. Java 容器 & 泛型:三、HashSet,TreeSet 和 LinkedHashSet比较

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 上一篇总结了下ArrayList .LinkedList和Vector比较,今天泥瓦匠总结下Hash ...