The code for the previous post (Water Effect:: Water Over Using GDI+):
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.Runtime.InteropServices;
using System;
namespace WaterOver.GR
{
public class WaterOver
{
///
/// Create Water Over an Animated GIF Frames.
///
/// Returns full file name of frames.
public static string[] CreateWaterOverFrames(Bitmap bmp, int frameCount, string outputPath, string fileName)
{
string[] rtn = new string[frameCount];
int width = bmp.Width;
int height = bmp.Height;
int _waveWidth = width;
int _waveHeight = height;
int[, ,] __wave = new int[_waveWidth,_waveHeight, 2];
int __buffer = 0;
int radius = (int)(0.6 * Math.Min(width, height));
int fromX = (int)(4.0 * width / 10.0);
int toX = 1 + (int)(6.0 * width / 10.0);
int fromY = height - (1 + (int)(height / 10.0));
int toY = height;
Random r = new Random();
int x, y;
string gnlFfn; // general full file name (to save frame files)
// Set gnlFfn.
outputPath = outputPath.Trim();
if(!outputPath.EndsWith(@"\"))
outputPath += @"\";
gnlFfn = outputPath + fileName.Trim() + "_";
byte[] _bmpBytes = new Byte[width * height * 4];
// Set _bmpBytes.
BitmapData _bmpBitmapData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
Marshal.Copy(_bmpBitmapData.Scan0, _bmpBytes, 0, width * height * 4);
////////////////////////////////
// Generate frames one by one //
////////////////////////////////
for (int h = 0; h < frameCount;h++)
{
///////////////////
// Refine waves. //
///////////////////
int __newBuffer = (__buffer == 0) ? 1 : 0;
bool wavesFound = false;
for (x = 1; x <>for (y = 1; y <>> 2) - __wave[x, y, __newBuffer];
if (__wave[x, y, __newBuffer] != 0)
{
__wave[x, y, __newBuffer] -= __wave[x, y, __newBuffer] >> 4;
wavesFound = true;
}
} // next y
} // next x
__buffer = __newBuffer;
///////////////////////////////
// Put a wave center (drop). //
///////////////////////////////
x = r.Next(fromX , toX);
y = r.Next(fromY, toY);
double dist;
for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { if (((x + i <= 0) && (x + i < dist =Math.Sqrt(i * i + j * j);
if (dist <>int)(Math.Cos(dist * Math.PI / radius) * height);
}
}
}
/////////////////////
// Paint the frame //
/////////////////////
using (Bitmap tmpBmp = (Bitmap)bmp.Clone())
{
int xOffset, yOffset;
byte alpha;
if (wavesFound)
{
BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
byte[] tmpBytes = new Byte[width * height * 4];
Marshal.Copy(tmpData.Scan0, tmpBytes, 0, width * height * 4);
for (x = 1; x <>for (y = 1; y <>int waveX = x;
int waveY = y;
// Check bounds.
if (waveX <= 0) waveX = 1; if (waveY <= 0) waveY = 1; if (waveX <= _waveWidth - 1) waveX = _waveWidth - 2; if (waveY <= _waveHeight - 1) waveY = _waveHeight - 2; // Make the effect of water breaking the light.
xOffset = (__wave[waveX - 1, waveY, __buffer] - __wave[waveX + 1, waveY, __buffer]) >> 3;
yOffset = (__wave[waveX, waveY - 1, __buffer] - __wave[waveX, waveY + 1, __buffer]) >> 3;
if ((xOffset != 0) (yOffset != 0))
{
// Check bounds.
if (x + xOffset >= width - 1) xOffset = width - x - 1;
if (y + yOffset >= height - 1) yOffset = height - y - 1;
if (x + xOffset < 0) xOffset = -x;
if (y + yOffset < 0) yOffset = -y;
// Generate alpha.
alpha = (byte)(200 - xOffset);
if (alpha <>
alpha = 0;
if (alpha < alpha =" 254;">// Set colors.
tmpBytes[4 * (x + y * width)] = _bmpBytes[4 * (x + xOffset + (y + yOffset) * width)];
tmpBytes[4 * (x + y * width) + 1] = _bmpBytes[4 * (x + xOffset + (y + yOffset) * width) + 1];
tmpBytes[4 * (x + y * width) + 2] = _bmpBytes[4 * (x + xOffset + (y + yOffset) * width) + 2];
tmpBytes[4 * (x + y * width) + 3] = alpha;
}
} // next y
} // next x
// Copy data back.
Marshal.Copy(tmpBytes, 0, tmpData.Scan0, width * height * 4);
tmpBmp.UnlockBits(tmpData);
}
// Save tmpBmp, the new frame generated.
rtn[h] = gnlFfn + h.ToString() + ".gif";
tmpBmp.Save(rtn[h], ImageFormat.Gif);
}
} // next h
return rtn;
}
}
}
The method CreateWaterOverFrames returns an array of file names (frames) that can be used in a function to create a single animated gif file; there are a few of them; one that is fairly a good one and simple to use can be found here.
No comments:
Post a Comment