• c# 图片带水纹波动


    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 = 50;
                myWaterTimer.Tick += new EventHandler(myWaterTimer_Tick);
                Timer 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 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;
            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 == null) return;
                Subject.UnlockBits(bitmapData);
                bitmapData = null;
                pBase = null;
                isLocked = false;
            }
        }
    }
  • 相关阅读:
    VIJOS1476 旅行规划(树形Dp + DFS暴力乱搞)
    神奇的图片
    How to locate elements/ Object locators for Android devices
    ZT: How to install appium with node.js
    How to get the appPackage and appActivity
    How to enable auto-complete for python in powershell
    Node.js
    Steps to develop an iterative algorithm
    Iterative Algorithm
    FSM
  • 原文地址:https://www.cnblogs.com/feizianquan/p/10295876.html
Copyright © 2020-2023  润新知