這是截屏動畫效果:
- #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