至此就完成了素材准備階段。一切就緒後,接下來的工作就是將主角8方向5動作的所有幀圖片(本例子中的272張)進行處理,最終合成一張將這所有圖片按一定規律排列的8方向5動作整合圖。就以這272張圖片為例,如何使用WPF類庫中的方法將它們合並為一張圖片呢?來看本節的第一個精華ComposeImage()方法:
/// <summary>
/// 將N幀圖片合成一張8方向角色各動作分布圖
/// </summary>
/// <param name="SourcePath">源文件路徑</param>
/// <param name="SavaToPath">保存文件到目標路徑</param>
/// <param name="imgnum">源圖片數量</param>
/// <param name="imgwidth">單位圖片寬</param>
/// <param name="imgheight">單位圖片高</param>
public static void ComposeImage(string SourcePath, string SavaToPath, int imgNum, int imgWidth, int imgHeight) {
System.IO.FileStream fileStream = new System.IO.FileStream(SavaToPath, System.IO.FileMode.Create);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
int count = 1;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < imgNum / 8; j++) {
drawingContext.DrawImage(new BitmapImage(new Uri(SourcePath + count + "-1.png")), new Rect(j * imgWidth, i * imgHeight, imgWidth, imgHeight));
count += 1;
}
}
drawingContext.Close();
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((imgNum / 8) * imgWidth, 8 * imgHeight, 0, 0, PixelFormats.Pbgra32);
renderTargetBitmap.Render(drawingVisual);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
encoder.Save(fileStream);
fileStream.Close();
}
我將該方法寫在一個名叫Super的靜態類中,關於它的參數意思在注釋中已經寫得很清楚了,至於它是如何實現將這272張圖片有規律的合成為1張我們能夠在後面使用的合成圖,大家只需要注意我用黃色突出的代碼,這是主要的算法邏輯(單張圖片的文件名格式如前文中的格式圖上的一樣,例如1-1.png、2-1.png、3-1.png、4-1.png、5-1.png、6-1.png……等等,如果你的圖片是1.png、2.png、3.png、4.png、5.png、6.png、7.png、8.png……等等這樣的取名格式,那麼只需要將"-1.png"換成".png"即可)。至於其它的部分大家稍微看一下就可以輕松理解了。
上圖上部分即為我調用Super.ComposeImage(@"E:\Body\", "Body0.png", 272, 150, 150);方法合成的主角8方向5動作的一張寬150*34=5100(34=5+8+7+6+8)像素、高150*8=1200(8=8個方向,按照上文中的順序)像素的整合圖。(由於該圖尺寸過大(5100*1200像素),所以我將之縮小為原尺寸的15%左右以供給大家展示)
從上圖下部分中(上部分的局部放大圖),大家可以很清晰的發現圖片排列的規律:即8行34列;從行看,由上至下的8行分別為代號0-7這8個方向的所有圖片;從列看,1-5列為站立幀圖片,6-13列為跑動幀圖片,14-20列為攻擊幀圖片,21-26列為施法幀圖片,27-34列為死亡幀圖片。理清了規律後,如何對它進行局部單圖截取?嘿嘿,且聽下回分解。