这是截屏动画效果:
- #region 旋转放大
- // 原理:使用Graphics的RotateTransform()方法进行坐标变换
- private void Animator21()
- {
- const float anglePer = 6; // 每次旋转的角度,应能被360整除
- const int roundCount = 2; // 旋转周数
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- //ClearBackground();
- for (float angle = anglePer; angle <= 360 * roundCount; angle += anglePer) // 每次旋转若干度度,同时进行缩放
- {
- dc.Clear(Color.FromKnownColor(KnownColor.ButtonFace)); // 清空DC的内容
- dc.TranslateTransform(bmp.Width / 2, bmp.Height / 2); // 平移坐标轴,以进行基于图片中心的旋转
- dc.RotateTransform(angle); // 旋转坐标轴
- dc.ScaleTransform(angle / 360 / roundCount, angle / 360 / roundCount); // 缩放
- dc.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2); // 平移坐标轴(复原),用于显示处理后的图像
- dc.DrawImage(bmp, 0, 0); // 在DC中绘制图像
- dc.ResetTransform(); // 重置DC的全部变换,准备下一次循环
- ShowBmp();
- Thread.Sleep(10 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 椭圆拉幕
- // 原理:使用TextureBrush载入图像,而后用Graphics的FillEllipse()方法逐渐扩大显示面积
- private void Animator22()
- {
- const int stepCount = 3; // 椭圆外接矩形的高每次的增量像素
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- TextureBrush textureBrush = new TextureBrush(bmp); // 创建材质画刷
- // 以高度为椭圆由小到大的增量
- // 系数1.5使椭圆加大,直到椭圆的内接矩形等于bmp尺寸
- // 系数1.5为当前长宽比椭圆的估算系数
- for (int i = 1; i <= 1.5 * bmp.Height / 2f; i += stepCount)
- {
- RectangleF rect = new RectangleF(bmp.Width / 2f - i * bmp.Width / bmp.Height, bmp.Height / 2 - i,
- 2 * i * bmp.Width / bmp.Height, 2 * i); // 在DC中心位置距离椭圆的外接矩形
- dc.FillEllipse(textureBrush, rect); // 填充
- ShowBmp(rect);
- Thread.Sleep(10 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 对角拉伸
- // 原理:使用Graphics的DrawImage()方法的一个重载版本,将图像绘制在平行四边形中
- private void Animator23()
- {
- const float stepCount = 4.5f; // 平行四边形左上定点所在矩形对角线的增量
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- // 绘制平行四边形的三个点为:左上、右上、左下
- // 平行四边形的右上、左下为固定点,不断改变左上点的坐标,使其趋于矩形
- // 平行四边形的左上点沿矩形对角线(中心到左上)方向改变,故先计算矩形对角线的一半,并以此为循环变量
- double diagonal = Math.Sqrt(Math.Pow(bmp.Width, 2f) + Math.Pow(bmp.Height, 2f)) / 2f; // 矩形对角线的一半
- double a = Math.Atan(Convert.ToDouble(bmp.Height) / bmp.Width); // 计算矩形对角线与底边(Width)的夹角
- for (double i = diagonal; i >= 0; i -= stepCount)
- {
- // 计算当前左上点的坐标
- Point point = new Point((int)(Math.Cos(a) * i), (int)(Math.Sin(a) * i));
- // 生成平行四边形左上、右上、左下坐标点数组
- Point[] points = { point, new Point(bmp.Width, 0), new Point(0, bmp.Height) };
- dc.DrawImage(bmp, points); // 将图像绘制在平行四边形中
- ShowBmp();
- Thread.Sleep(10 * delay);
- }
- // 平行四边形左上定点的位置最终不必定为(0, 0),故在循环结束后绘制整个位图
- dc.DrawImage(bmp, 0, 0);
- ShowBmp();
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 旋转扫描
- // 原理:使用TextureBrush载入图像,而后用Graphics的FillPie()方法逐渐扩大扇形显示面积
- private void Animator24()
- {
- const int anglePer = 5; // 每次旋转的角度,应能被360整除
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- // 创建椭圆外接矩形区域,该区域的内接椭圆的内接矩形应不小于bmp尺寸
- // 内部使用BitBlt() API函数,大的区域基本不会影响速度
- // 坐标平移后应保证该矩形的内接椭圆中心与bmp中心重合
- Rectangle rect = new Rectangle(-bmp.Width, -bmp.Height, bmp.Width * 3, bmp.Height * 3);
- TextureBrush textureBrush = new TextureBrush(bmp); // 创建材质画刷
- // 以扇形跨越角度(单位度)为增量,即角速度相等,线速度并不相等
- for (int i = 0; i <= 360; i += anglePer)
- {
- dc.FillPie(textureBrush, rect, 180, i); // 填充扇形
- ShowBmp(rect);
- Thread.Sleep(10 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 多径扫描
- // 原理:使用TextureBrush载入图像,而后用Graphics的FillPie()方法分多个角度同步显示逐渐扩大的扇形区域
- private void Animator25()
- {
- const float pieCount = 8; // 同时扫描的扇形数量
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- // 创建椭圆外接矩形区域,该区域的内接椭圆的内接矩形应不小于bmp尺寸
- // 内部使用BitBlt() API函数,大的区域基本不会影响速度
- // 坐标平移后应保证该矩形的内接椭圆中心与bmp中心重合
- Rectangle rect = new Rectangle(-bmp.Width, -bmp.Height, bmp.Width * 3, bmp.Height * 3);
- TextureBrush textureBrush = new TextureBrush(bmp); // 创建材质画刷
- // 以扇形跨越角度(单位度)为增量,即角速度相等,线速度并不相等
- // 共pieCount个扇形每一个扇形共计360/pieCount度
- for (int angle = 1; angle <= Math.Ceiling(360 / pieCount); angle++)
- {
- // 扫描每一个扇形区域
- for (int i = 0; i < pieCount; i++)
- {
- dc.FillPie(textureBrush, rect, i * 360 / pieCount, angle); // 填充扇形
- }
- ShowBmp(rect);
- Thread.Sleep(20 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 随机落幕(改进版)
- // 原理:将图像分红宽度相等的列,而后每次随机若干列前进必定的量,直到全部的竖条均到达图像底端
- private void Animator26()
- {
- const float lineWidth = 15; // 竖条宽度
- const int stepCount = 6; // 竖条每次前进量
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- int colCount = (int)Math.Ceiling(bmp.Width / lineWidth); // 计算列数
- Random rnd = new Random(); // 随机数类
- // 该数组保存每一个列前进的位置,即每一个列的高度,自动初始化为0
- int[] colIndex = new int[colCount];
- // 按随机次序逐一显示每一个竖条
- bool flag = false; // 表示是否全部的列均显示完成,即到达了图像的底边
- Region region = new Region(new GraphicsPath()); // 空区域
- TextureBrush textureBrush = new TextureBrush(bmp); // 创建位图材质画刷
- do // 循环直到全部列均显示完毕,即到达底端
- {
- for (int i = 0; i < colCount; i++)
- {
- int col = rnd.Next(colCount); // 随机生成要显示的列
- if (colIndex[col] < bmp.Height) // 该列未显示完
- {
- colIndex[col] += stepCount; // 记录该列新的位置
- RectangleF rect = new RectangleF(col * lineWidth, 0, lineWidth, colIndex[col]);
- region.Union(rect);
- }
- else
- {
- i--; // 保证每次处理列数为colCount
- }
- }
- dc.FillRegion(textureBrush, region);
- ShowBmp(region.GetBounds(dc));
- Thread.Sleep(10 * delay);
- flag = true; // 假设全部列已显示完成
- for (int i = 0; i < colIndex.Length; i++)
- {
- if (colIndex[i] < bmp.Height)
- {
- flag = false; // 存在未显示完的列,仍需循环
- break;
- }
- }
- } while (!flag);
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 螺线内旋
- // 原理:从图像左上角开始,以分块大小顺时针内旋显示图像
- private void Animator27()
- {
- const float blockSize = 45; // 正方块的边长
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- int cols = (int)Math.Ceiling(bmp.Width / blockSize); // 按照分块尺寸划分的列总计
- int rows = (int)Math.Ceiling(bmp.Height / blockSize); // 按照分块尺寸划分的行总计
- Point block = new Point(0, 0); // 当前显示块的坐标
- Rectangle area = new Rectangle(0, 0, cols, rows); // 还没有显示分块的区域坐标
- int direction = 0; // 内旋方向,0表示向右,1表示向下,2表示向左,3表示向上
- for (int i = 0; i < cols * rows; i++) // 循环分块总数次
- {
- RectangleF rect = new RectangleF(block.X * blockSize, block.Y * blockSize, blockSize, blockSize);
- dc.DrawImage(bmp, rect, rect, GraphicsUnit.Pixel);
- switch (direction)
- {
- case 0: // 当前向右
- if (block.X < area.Width - 1) // 还没有到达右边界
- {
- block.X++; // 继续向右
- }
- else // 已到达右边界
- {
- direction = 1; // 方向改成向下
- block.Y++; // 向下
- area.Y++; // 修改待显示区域的上边界
- }
- break;
- case 1: // 当前向下
- if (block.Y < area.Height - 1) // 还没有到达下边界
- {
- block.Y++; // 继续向下
- }
- else // 已到达下边界
- {
- direction = 2; // 方向改成向左
- block.X--; // 向左
- area.Width--; // 修改待显示区域的右边界
- }
- break;
- case 2: // 当前向左
- if (block.X > area.X) // 还没有到达左边界
- {
- block.X--; // 继续向左
- }
- else // 已到达左边界
- {
- direction = 3; // 方向改成向上
- block.Y--; // 向上
- area.Height--; // 修改待显示区域的下边界
- }
- break;
- default: // 当前向上
- if (block.Y > area.Y) // 还没有到达上边界
- {
- block.Y--; // 继续向上
- }
- else // 已到达上边界
- {
- direction = 0; // 方向改成向右
- block.X++; // 向右
- area.X++; // 修改待显示区域的左边界
- }
- break;
- }
- ShowBmp(rect);
- Thread.Sleep(10 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 灰度扫描(改进版)
- // 原理:使用ImageAttributes类和颜色转换矩阵处理图像,从下到上灰度显示图像,而后从上到下转换为正片
- private void Animator28()
- {
- const int stepCount = 6; // 每次显示的像素量
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- // ImageAttributes类的实例用于调整颜色,由DrawImage()方法调用
- ImageAttributes attributes = new ImageAttributes();
- // 创建5*5阶RGBA颜色矩阵
- ColorMatrix matrix = new ColorMatrix();
- // 根据亮度方程将矩阵设为灰度变换
- for (int i = 0; i < 3; i++)
- {
- matrix[0, i] = 0.299f;
- matrix[1, i] = 0.587f;
- matrix[2, i] = 0.114f;
- }
- attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
- // 创建灰度位图并将输入位图转换为灰度
- Bitmap grayBmp = new Bitmap(bmp.Width, bmp.Height);
- Graphics grayDc = Graphics.FromImage(grayBmp);
- grayDc.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attributes);
- // 以灰度方式从下到上绘制整个图像
- for (int y = bmp.Height - 1; y >= 0; y -= stepCount)
- {
- Rectangle rect = new Rectangle(0, y, bmp.Width, stepCount);
- dc.DrawImage(grayBmp, rect, rect, GraphicsUnit.Pixel);
- ShowBmp(rect);
- Thread.Sleep(10 * delay);
- }
- // 以正片方式从上到下绘制整个图像
- for (int y = 0; y < bmp.Height; y += stepCount)
- {
- Rectangle rect = new Rectangle(0, y, bmp.Width, stepCount);
- dc.DrawImage(bmp, rect, rect, GraphicsUnit.Pixel);
- ShowBmp(rect);
- Thread.Sleep(10 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 负片追踪(改进版)
- // 原理:使用ImageAttributes类和颜色转换矩阵处理图像,从左到右负片显示图像,同时,以滞后方式显示正片
- private void Animator29()
- {
- const float stepCount = 4; // 每次显示的像素量
- const float delayCount = 280; // 转换为正片的滞后像素数,该值必须能被stepCount整除
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- // ImageAttributes类的实例用于调整颜色,由DrawImage()方法调用
- ImageAttributes attributes = new ImageAttributes();
- // 创建5*5阶RGBA颜色矩阵
- ColorMatrix matrix = new ColorMatrix();
- // 将矩阵设为负片变换
- matrix.Matrix00 = matrix.Matrix11 = matrix.Matrix22 = -1f;
- matrix.Matrix30 = matrix.Matrix31 = matrix.Matrix32 = 1f;
- attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
- // 创建负片图像
- Bitmap negativeBmp = new Bitmap(bmp.Width, bmp.Height);
- // 转换负片图像
- Graphics negativeDc = Graphics.FromImage(negativeBmp);
- negativeDc.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attributes);
- // 以负片方式从左到右绘制整个图像,正片绘制在负片进行到delay时开始,并以合适的速度前进,刚好与负片同时到达右边
- for (int x = 0; x < bmp.Width; x += (int)stepCount)
- {
- // 负片显示区域
- RectangleF rect1 = new RectangleF(x, 0, stepCount, bmp.Height);
- dc.DrawImage(negativeBmp, rect1, rect1, GraphicsUnit.Pixel);
- RectangleF rect2 = RectangleF.Empty;
- if (x >= delayCount) // 显示正片区域
- {
- // 正片显示区域计算方法:
- // 正片起始位置:(x - delay) * bmp.Width / (bmp.Width - delay)
- // 当前负片已显示到delay,还需显示bmp.Width - delay,而正片还需显示bmp.Width
- // 即负片每显示一次,正片需显示负片的bmp.Width / (bmp.Width - delay)倍
- // 所以,正片每次的起始位置为(x - delay) * bmp.Width / (bmp.Width - delay)
- // 正片增量:bmp.Width / ((bmp.Width - delay) / stepCount)
- // 正片共需显示bmp.Width
- // 负片还有((bmp.Width - delay) / stepCount)次便显示完成,即正片也有一样的次数
- // 所以,正片每次显示bmp.Width / ((bmp.Width - delay) / stepCount)
- rect2 = new RectangleF((x - delayCount) * bmp.Width / (bmp.Width - delayCount), 0,
- bmp.Width / ((bmp.Width - delayCount) / stepCount), bmp.Height);
- dc.DrawImage(bmp, rect2, rect2, GraphicsUnit.Pixel);
- }
- ShowBmp(RectangleF.Union(rect1, rect2));
- Thread.Sleep(10 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- #region 水平卷轴
- // 原理:从左到右显示逐步图像,在已显示区域的右边缘压缩显示剩余图像
- private void Animator30()
- {
- const float blockWidth = 80; // 压缩图像区域的宽度(像素)
- const float stepCount = 6; // 每次显示步进宽度(像素)
- try
- {
- OnDrawStarted(this, EventArgs.Empty);
- ClearBackground();
- for (int x = 0; x <= Math.Ceiling((bmp.Width - blockWidth) / stepCount); x++)
- {
- // 绘制不压缩的显示区域
- RectangleF rect = new RectangleF(x * stepCount, 0, stepCount, bmp.Height);
- dc.DrawImage(bmp, rect, rect, GraphicsUnit.Pixel);
- // 绘制压缩区域
- RectangleF sourRect = new RectangleF((x + 1) * stepCount, 0, bmp.Width - x * stepCount, bmp.Height); // 还没有显示的区域
- RectangleF destRect = new RectangleF((x + 1) * stepCount, 0, blockWidth, bmp.Height); // 压缩竖条区域
- dc.DrawImage(bmp, destRect, sourRect, GraphicsUnit.Pixel);
- ShowBmp(RectangleF.Union(rect, destRect));
- Thread.Sleep(10 * delay);
- }
- }
- catch (Exception ex)
- {
- ShowError(ex.Message);
- }
- finally
- {
- OnDrawCompleted(this, EventArgs.Empty);
- }
- }
- #endregion
- }
- }
下面的连接或附件能够下载该软件完整的源文件,包含全部资源和一个已编译的可执行文件,至少须要.NET 3.5架构支持:
http://mengliao.blog.51cto.com/p_w_upload/201101/876134_1294304450.rar
(全文完)windows