gpt4 book ai didi

c# - 我该如何将这种方法从Winforms转换为WPF?

转载 作者:太空狗 更新时间:2023-10-30 00:28:41 26 4
gpt4 key购买 nike

我有一个简单的程序,可以根据一系列数字(1到10)创建一系列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);
}

我想做的是把这个空白转换成wpf。我目前对wpf没有经验,因此我没有问题。
目标框架是4.0
非常感谢你的帮助。

最佳答案

绘图是winforms而不是wpf的一部分
首先我想澄清一个误会。
基于win32的gdi+的system.drawing实际上是winforms的一个组件。wpf不是基于它构建的,silverlight和wpf到其他平台的其他端口可能永远不会包含它,并且system.drawing(winforms)使用的约定与system.windows.media(wpf)使用的约定之间存在许多不兼容。例如,它们使用不同的测量单位(像素与固定96dpi)、不同的坐标类型(int与double)、不同的线绘制规则、不同的旋转、不同的笔刷、立即模式与保留模式等。
wpf的System.Windows.Media库比winforms的System.Drawing(gdi+)库强大得多。wpf包含更多的变换、更好的不透明度支持、3d和其他功能,这些功能允许使用System.Drawing(gdi+)时非常困难的效果。
但问题中提出的代码无论如何都能与wpf一起工作吗?
会的。只要您在wpf上运行而不是像silverlight这样的克隆,您仍然可以访问旧的winforms库。所以您可以继续使用System.Drawing调用来绘制您的图形。但是,不能将生成的位图简单地放到wpf应用程序中:位图不兼容,通常wpf位图更强大。有多种方法可以将位图转换为wpf位图,也可以将其保存为标准文件格式(如.png)并重新加载。
由于问题中提出的代码实际上将位图保存到了一个.png文件中,因此实际上可以不加修改地使用它。但是,如果在创建位图时需要任何新的wpf特性,或者如果希望在不保存到文件的情况下使用位图,则需要特殊的技术。
那你为什么不按原样使用这些代码呢?
也许你会这样做:如果你正在做一个快速的应用程序,并且已经编写了代码,而且你确实想将文件存储到磁盘上,那么就没有理由将代码转换为wpf。但是,如果您想使用新的wpf特性,或者使用数据绑定或其他动态技术将图像直接合并到wpf用户界面中,则可能需要将程序转换为使用wpf的库,而不是使用winforms。这是一个基于你需要的判断电话。
您的问题是,要使此代码“与wpf一起工作”需要什么。答案是:没什么。您的代码编写普通的.png文件,wpf读取普通的.png文件。所以它会起作用的。
如果你的代码是90年代的cobol、java或其他任何调用基于unix的绘图库的原始语言,也可以这么说,只要代码最终编写了一个标准的.png文件(或.gif或.jpg或…),它的输出就可以使用wpf。正如有令人信服的理由不将代码留在COBOL或Java中一样,也有理由不将代码留在使用System.Drawing:
依赖于系统。随着时间的推移,wpf可能出现,也可能不出现。
你能画的东西的限制
与其他wpf代码不同的绘图模型
那么我该如何使用wpf而不是winforms来完成这项工作呢?
您可以使用以下三个简单步骤,使用wpf中显示的任何内容制作位图:
使用xaml或代码构造wpf可视化。
在代码中,构造所需大小的renderTargetBitmap,然后调用.render(可视化)
在应用程序的其他位置使用生成的位图,或者使用pngbitmapecoder或类似工具保存它。
对于您的特定示例,我可能会使用这样的数据模板:

<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
}

关于c# - 我该如何将这种方法从Winforms转换为WPF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2256411/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com