zoukankan      html  css  js  c++  java
  • C#自定义控件七水波纹

    C#自定义控件七水波纹

    效果图:

    这个是网上搞来的,本人修改了一小点代码,不过用C#写这个效率有点低,还是汇编写的最好。

    贴出全部代码:

    //控件名:myWaterWave

    //作者:刘典武

    //时间:2011-06-09

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Drawing;

    using System.Data;

    using System.Text;

    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 myWaterWave : UserControl

        {

            public myWaterWave()

            {

                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);

                myWaterTimer = new Timer();

                myWaterTimer.Interval = 50;

                myWaterTimer.Tick += new EventHandler(myWaterTimer_Tick);

                myDropsTimer = new Timer();

                myDropsTimer.Interval = 50000;

                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);

                    int _drop = 0;

                    for (int i = 0; i < _dropsNumber; i++)

                    {

                        _drop = r.Next(drops.Length);

                        DropWater(drops[_drop].x, drops[_drop].y, drops[_drop].radius, drops[_drop].height);

                    }

                    this.myDropsTimer.Interval = r.Next(15 * _percent) + 1;

                    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 int bitmapWidth = 0;

            private static int bitmapHeight = 0;

            private static int bits = 4;

            private static DropData[] drops;

            private FastBitmap fastImage = null;

            private FastBitmap originalImage = null;

            public int currentHeightBuffer = 0;

            public int newHeightBuffer = 0;

            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][][];

                    for (int i = 0; i < bitmapWidth; i++)

                    {

                        waveHeight[i] = new int[bitmapHeight][];

                        for (int j = 0; j < bitmapHeight; j++)

                        {

                            waveHeight[i][j] = new int[2];

                        }

                    }

                    CreateBitmap();

                    if (auto)

                    {

                        CreateWaterDrops();

                        this.myWaterTimer.Enabled = true;

                        this.myDropsTimer.Interval = 50;

                        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, 0, 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;

                        if ((_x >= 0) && (_x <= bitmapWidth - 1) && (_y >= 0) && (_y <= bitmapHeight - 1))

                        {

                            _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 + 1) % 2;

                fastImage.LockBits();

                byte[] _bufferBits = new byte[bits * fastImage.Width() * fastImage.Height()];

                Marshal.Copy(fastImage.Data().Scan0, _bufferBits, 0, _bufferBits.Length);

                int _offX;

                int _offY;

                for (int _x = 1; _x < bitmapWidth - 1; _x++)

                {

                    for (int _y = 1; _y < bitmapHeight - 1; _y++)

                    {

                        unchecked

                        {

                            waveHeight[_x][_y][newHeightBuffer] = ((

                                waveHeight[_x - 1][_y][currentHeightBuffer] +

                                waveHeight[_x - 1][_y - 1][currentHeightBuffer] +

                                waveHeight[_x][_y - 1][currentHeightBuffer] +

                                waveHeight[_x + 1][_y - 1][currentHeightBuffer] +

                                waveHeight[_x + 1][_y][currentHeightBuffer] +

                                waveHeight[_x + 1][_y + 1][currentHeightBuffer] +

                                waveHeight[_x][_y + 1][currentHeightBuffer] +

                                waveHeight[_x - 1][_y + 1][currentHeightBuffer]) >> 2)

                            - waveHeight[_x][_y][newHeightBuffer];

                        }

                        waveHeight[_x][_y][newHeightBuffer] -= (waveHeight[_x][_y][newHeightBuffer] >> 5);

                        _offX = ((waveHeight[_x - 1][_y][newHeightBuffer] - waveHeight[_x + 1][_y][newHeightBuffer])) >> 3;

                        _offY = ((waveHeight[_x][_y - 1][newHeightBuffer] - waveHeight[_x][_y + 1][newHeightBuffer])) >> 3;

                        if ((_offX == 0) && (_offY == 0)) continue;

                        if (_x + _offX <= 0) _offX = -_x;

                        if (_x + _offX >= bitmapWidth - 1) _offX = bitmapWidth - _x - 1;

                        if (_y + _offY <= 0) _offY = -_y;

                        if (_y + _offY >= bitmapHeight - 1) _offY = bitmapHeight - _y - 1;

                        _bufferBits[bits * (_x + _y * bitmapWidth) + 0] = bitmapOriginalBytes[bits * (_x + _offX + (_y + _offY) * bitmapWidth) + 0];

                        _bufferBits[bits * (_x + _y * bitmapWidth) + 1] = bitmapOriginalBytes[bits * (_x + _offX + (_y + _offY) * bitmapWidth) + 1];

                        _bufferBits[bits * (_x + _y * bitmapWidth) + 2] = bitmapOriginalBytes[bits * (_x + _offX + (_y + _offY) * bitmapWidth) + 2];

                    }

                }

                Marshal.Copy(_bufferBits, 0, 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];

                for (int i = 0; i < drops.Length; i++)

                {

                    _dropX = r.Next(bitmapWidth);

                    _dropY = r.Next(bitmapHeight);

                    _height = r.Next(400);

                    _dropRadius = r.Next(4 * _percent);

                    if (_dropRadius < 4) _dropRadius = 4;

                    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, 0, 0, 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 = new DropData[1];

                dropX = e.X;

                dropY = e.Y;

                height = r.Next(400);

                dropRadius = r.Next(4 * percent);

                if (dropRadius < 4) dropRadius = 4;

                drops[0].x = dropX;

                drops[0].y = dropY;

                drops[0].radius = dropRadius;

                drops[0].height = height;

                this.myWaterTimer.Enabled = true;

                this.myDropsTimer.Interval = 50;

                this.myDropsTimer.Enabled = true;

            }

            private void myWaterWave_MouseLeave(object sender, EventArgs e)

            {

                this.myDropsTimer.Enabled = false;

            }

        }

        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;

            int _bits = 0;

            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);

                    if (SubjectWidth % _bits != 0)

                    {

                        SubjectWidth = _bits * (SubjectWidth / _bits + 1);

                    }

                    if (_bits == 3)

                        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 == nullreturn;

                Subject.UnlockBits(bitmapData);

                bitmapData = null;

                pBase = null;

                isLocked = false;

            }

        }

    }

    搞定!休息下!呵呵!请假回家相亲咯!


  • 相关阅读:
    sql性能调优的注意项
    mybatis获取刚插入数据的ID
    mysql
    JQuery
    JS
    css
    web前端
    python爬虫
    socket编程
    python基础
  • 原文地址:https://www.cnblogs.com/feiyangqingyun/p/2101234.html
Copyright © 2011-2022 走看看