我有一个简单的程序,可以根据一系列数字创建一系列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);
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是将此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>
Run Code Online (Sandbox Code Playgroud)
那么你写出文件的实际代码是:
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
});
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以省略模板,只需在代码中构造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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |