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. EF学习笔记(十) 处理并发

    总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上一篇:EF学习笔记(九):异步处理和存储过程 本篇原文链接:Handling Concurrency Concurrency ...

  2. 报错:Maximum call stack size exceeded

    最后通过查看一篇别人的博客,通过对照,发现我把参数值写反了,把参数a的值写成了参数b的值.详情可以看如下博客: https://www.cnblogs.com/dunitian/p/5865725.h ...

  3. JAVA核心技术第二卷 第一章

    流的家族:

  4. HttpServletRequest.getContextPath()取得的路径

    如果项目名称为test,你在浏览器中输入请求路径:http://localhost:8080/test/pc/list.jsp 执行下面向行代码后打印出如下结果: 1. System.out.prin ...

  5. SQL Server 深入解析索引存储(非聚集索引)

    标签:SQL SERVER/MSSQL SERVER/数据库/DBA/索引体系结构/非聚集索引 概述 非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: 基础表的数据行不按非 ...

  6. App设计:消息推送和界面路由跳转

    概要 app消息推送.显示通知栏,点击跳转页面是很一般的功能了,下面以个推为例演示push集成,消息处理模块及app内部路由模块的简单设计. 推送 推送sdk集成 集成sdk步骤根据文档一步步做就行了 ...

  7. PMS权限管理和鉴权过程

    一.权限的管理基础知识 1.系统的权限机制分为:权限解析.权限分配.鉴权.动态添加权限 2.PermissionInfo :  PackageParser.Permission中包含一个对应的Perm ...

  8. bash 管理小脚本

    #!/bin/bash shell_user="root" shell_pass="1233" shell_port="22" shell_ ...

  9. LeetCode题解33.Search in Rotated Sorted Array

    33. Search in Rotated Sorted Array Suppose an array sorted in ascending order is rotated at some piv ...

  10. dubbo集群容错解决方案

    dubbo主要核心部件 Remoting:网络通信框架,实现了sync-over-async和request-response消息机制. RPC:一个远程过程调用的抽象,支持负载均衡.容灾和集群功能. ...