C#实现的水纹特效
发布时间:2010年03月06日点击数:
次佚名
- using System;
- using System.Drawing;
- using System.Drawing.Imaging;
- namespace WaterWave
- {
- public sealed unsafe class WaterWave : IDisposable
- {
- private Bitmap _orgImage = null;
- private Bitmap _newImage = null;
- private BitmapData _orgData = null;
- private byte* _pOrgBase;
- private int _width;
- private int[,] _buf1, _buf2;
- private int _rippleCount = int.MaxValue;
- public WaterWave(Bitmap bitmap)
- {
- _orgImage = (Bitmap)bitmap.Clone();
- _newImage = (Bitmap)bitmap.Clone();
- Width = bitmap.Width;
- Height = bitmap.Height;
- _orgData = _orgImage.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
- _pOrgBase = (byte*)_orgData.Scan0.ToPointer();
- _width = Width * 3;
- if(_width % 4 != 0)
- _width = 4 * (_width / 4 + 1);
- _buf1 = new int[Width, Height];
- _buf2 = new int[Width, Height];
- }
-
-
-
- public int Width { get; private set; }
-
-
-
- public int Height { get; private set; }
-
-
-
- private void RippleSpread()
- {
- for(int i = 1;i < Width - 1;i++)
- for(int j = 1;j < Height - 1;j++)
- {
- _buf2[i, j] = ((_buf1[i - 1, j] + _buf1[i + 1, j] + _buf1[i, j - 1] + _buf1[i, j + 1]) >> 1) - _buf2[i, j];
- _buf2[i, j] -= _buf2[i, j] >> 5;
- }
- int[,] t = _buf1;
- _buf1 = _buf2;
- _buf2 = t;
- }
-
-
-
- private void RenderRipple()
- {
- _newImage = new Bitmap(Width, Height);
- BitmapData newData = _newImage.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
- byte* pBase = (byte*)newData.Scan0.ToPointer();
- int dx, dy;
- for(int i = 1;i < Width - 1;i++)
- for(int j = 1;j < Height - 1;j++)
- {
- dx = _buf1[i, j - 1] - _buf1[i, j + 1];
- dy = _buf1[i - 1, j] - _buf1[i + 1, j];
- if(i + dx < 0 || i + dx >= Width || j + dy < 0 || j + dy >= Height)
- continue;
-
- *(pBase + j * _width + i * 3) = *(_pOrgBase + (j + dy) * _width + (i + dx) * 3);
- *(pBase + j * _width + i * 3 + 1) = *(_pOrgBase + (j + dy) * _width + (i + dx) * 3 + 1);
- *(pBase + j * _width + i * 3 + 2) = *(_pOrgBase + (j + dy) * _width + (i + dx) * 3 + 2);
- }
- _newImage.UnlockBits(newData);
- }
-
-
-
-
-
- public void DropStone(Point point)
- {
- _buf1[point.X, point.Y] -= 100;
- _rippleCount = 90;
- }
-
-
-
-
- public Bitmap GetFrame()
- {
- if(_rippleCount > 0)
- {
- RippleSpread();
- RenderRipple();
- _rippleCount--;
- }
- return _newImage;
- }
- #region IDisposable Members
- public void Dispose()
- {
- if(_orgData != null)
- _orgImage.UnlockBits(_orgData);
- _orgData = null;
- }
- #endregion
- }
- }