![](/img/trans.png)
[英]How would I go about creating a ReturnAlteredObject extension method?
[英]How would I go about translating this method from Winforms to WPF?
我有一個簡單的程序,可以根據一系列數字創建一系列PNG圖像,即; 我遍歷每個數字,並以各種大小創建該數字的png圖像。 以下是我用來創建圖像的空白。
private void CreatePNG(int number, string location, int width, int height)
{
string filename = number.ToString() + "-" + width.ToString() + "x" + height.ToString() + ".png";
Bitmap b = new Bitmap(width, height);
Graphics g = Graphics.FromImage((System.Drawing.Image)b);
g.FillRectangle(Brushes.White, 0f, 0f, width, height);
StringFormat f = new StringFormat();
f.Alignment = StringAlignment.Center;
f.LineAlignment = StringAlignment.Center;
g.DrawString(number.ToString(), new Font("Helvetica", 55), Brushes.Black, new RectangleF(0, 0, width, height), f);
b.Save(location + "\\" + filename, ImageFormat.Png);
}
我想要做的是將此void轉換為與WPF一起使用。 我目前對WPF沒有經驗,因此我的noobie問題。
目標框架是4.0
非常感謝幫助。
System.Drawing是WinForms NOT WPF的一部分
首先,我想澄清一個誤解。
System.Drawing基於Win32的GDI +,實際上是WinForms的一個組件。 WPF不是基於它構建的,Silverlight和其他平台的WPF端口可能永遠不會包含它,並且System.Drawing(WinForms)使用的約定與System.Windows.Media(WPF)使用的約定之間存在許多不兼容性。 。 例如,他們使用不同的度量單位(像素與固定的96dpi),不同的坐標類型(int vs double),不同的線條繪制規則,不同的旋轉,不同的brushm,立即vs保留模式等。
WPF的System.Windows.Media
庫比WinForms的System.Drawing
(GDI +)庫強大得多。 WPF包含更多變換,更好的不透明度支持,3D和其他功能,允許使用System.Drawing
(GDI +)非常困難的效果。
但是,問題中提出的代碼是否可以與WPF一起使用?
是的,它會的。 只要您在WPF上運行而不是像Silverlight這樣的克隆,您仍然可以訪問舊的WinForms庫。 因此,您可以繼續使用System.Drawing
調用來繪制您的圖形。 但你無法獲取生成的Bitmap並將其簡單地插入到WPF應用程序中:位圖是不兼容的,並且像往常一樣WPF位圖更強大。 有一些方法可以將位圖轉換為WPF位圖,或者可以將其保存為標准文件格式(如.png)並重新加載。
由於問題中提出的代碼實際上確實將位圖保存為.png文件,因此實際上可以不加改變地使用它。 但是,如果在創建位圖時需要任何新的WPF功能,或者如果要在不保存到文件的情況下使用位圖,則需要特殊技術。
那你為什么不想按原樣使用這段代碼呢?
也許你會這樣:如果你正在做一個快速的應用程序並且已經編寫了代碼,並且你確實想要將文件存儲到磁盤,那么沒有理由將代碼轉換為WPF。 但是,如果您想使用新的WPF功能或使用數據綁定或其他動態技術將圖像直接合並到WPF用戶界面,您可能希望將程序轉換為使用WPF的庫而不是使用WinForms。 這是根據您的需求進行的判斷。
您的問題詢問了使用此代碼“使用WPF”所需的條件。 答案是:沒什么。 您的代碼編寫普通的.png文件,WPF讀取普通的.png文件。 所以它會奏效。
如果您的代碼是使用COBOL或Java或任何其他原始語言從90年代調用基於Unix的繪圖庫,則可以說同樣的事情。 只要代碼最終編寫標准.png文件(或.gif或.jpg或...),其輸出將與WPF一起使用。 正如有令人信服的理由不將代碼保留在COBOL或Java中一樣,有理由不使用System.Drawing保留代碼:
那么我如何使用WPF來代替WinForms呢?
您可以使用三個簡單的步驟從WPF中顯示的任何內容中制作位圖:
對於您的特定示例,我可能會使用如下的DataTemplate:
<DataTempate x:Key="NumberTemplate">
<TextBlock
Background="White"
HorizontalAlignment="Center" VerticalAlignment="Center"
FontFamily="Helvetica" FontSize="55"
Text="{Binding}"
/>
</DataTemplate>
然后你寫出文件的實際代碼是:
void CreatePng(int number, string location, int width, int height)
{
WritePng(location + "/" + number + "-" + width + "x" + height + ".png",
new ContentPresenter // Invokes a DataTemplate on its content
{
Content = number.ToString(),
Template = NumberTemplate,
Width = width, Height = height
});
}
或者,您可以省略模板,只需在代碼中構造TextBlock來代替ContentPresenter。 但是模板可以很容易地快速改變你的外觀並添加不透明度,漸變畫筆,位圖效果等花哨的東西,所以我建議使用模板,除非你絕對確定你的外觀永遠不會改變。
WritePng()方法是一個通用的單幀.png文件編寫器,它在一個簡單的界面中封裝了WPF的高級功能。 它的編碼如下:
void WritePng(string path, UIElement element)
{
// Create the bitmep specifying the size, pixel format and DPI
var bitmap = new RenderTargetBitmap((int)element.Width, (int)element.Height,
96, 96, PixelFormats.Pbgra32);
bitmap.Render(element); // At this point the bitmap is usable within WPF
// Write to a file: WPF can write multiple frames but we need only one
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using(Stream stream = File.Create(path))
encoder.Save(stream); // Could be any stream, not just a file
}
我認為,這在WPF中會運行得很好。 它使用的是System.Drawing
,而不是System.Windows.Forms
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.