WPF 基础绘图 创建和加工图片

这篇具有很好参考价值的文章主要介绍了WPF 基础绘图 创建和加工图片。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文将从控制台开始,告诉大家一个非常简单的 WPF 基础绘图方法,通过本文的方法可以调用 WPF 上层人类友好的方法,充分利用 GPU 资源,创建或加工图片,最终结果可以输出到本地文件,可支持编码出多种不同的图片格式

本文仅用到 WPF 的多媒体渲染层,在 WPF 的这一层上的 API 是人类友好的,直接咱使用的是就是熟悉的 DrawingContext 类型。通过 DrawingContext 进行画线、画矩形、画几何、画图片、画文字,进行裁剪、变换、加特效等等,即可绘制出绚酷的界面效果。经由 RenderTargetBitmap 和 BitmapEncoder 即可将界面编码为图片输出到文件里面

从本质上讲,本文的方法里面只是将 WPF 当成一个对 WIC (Windows Imaging Component) 层以及 DirectX 层的高级封装库,没有用到 WPF 更多好用的功能

回到主题,先创建一个控制台项目,在控制台项目里面打上 WPF 的负载,加上之后的 csproj 项目文件的代码如下

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <UseWpf>true</UseWpf>
  </PropertyGroup>

</Project>

在控制台里面要么在 Main 函数标记 STAThread 特性,要么自己新建一个 STA 线程,由于我之前的博客大量介绍的都是在 Main 函数上标记 STAThread 特性,于是我准备在这篇博客换一个玩法,就是自己新建一个 STA 线程。相对来说新建一个线程的代码会稍微多一点点

var thread = new Thread(() =>
{
    ... // 等待添加更多代码
});

thread.SetApartmentState(ApartmentState.STA);
thread.Start();

完成线程创建之后,即可在以上的 等待添加更多代码 里面加上 WPF 应用的初始化,在 WPF 应用的初始化里面自动将包含大量的初始化工作,简单的代码如下

var thread = new Thread(() =>
{
    var application = new Application();
    application.Startup += Application_Startup;
    application.Run();
});

在 Startup 事件里面执行真正的处理绘图相关逻辑,以上代码的 Application_Startup 的基础实现逻辑如下

先创建 DrawingVisual 对象,通过此对象即可获取到 DrawingContext 以执行绘图逻辑

void Application_Startup(object sender, StartupEventArgs e)
{
    var drawingVisual = new DrawingVisual();
    ... // 等待添加更多代码
}

从 DrawingVisual 里面获取 DrawingContext 的代码如下

    var drawingVisual = new DrawingVisual();
    using (DrawingContext drawingContext = drawingVisual.RenderOpen())
    {
        ... // 等待添加更多代码
    }

通过 DrawingContext 的 DrawXxx 系列方法即可绘制出有趣的界面效果,比如本文例子中绘制简单的矩形的代码

    using (var drawingContext = drawingVisual.RenderOpen())
    {
        drawingContext.DrawRectangle(Brushes.Black, pen: null, new Rect(0, 0, 1024, 768));
    }

实际使用中,可以在此替换为你所需的各种代码,包括先绘制图片,再绘制文本,从而制作文本水印等等。也可以加上更多复杂的编程控制逻辑,绘制更复杂的图片。如绘制从本地文件读取出来的图片,请参阅 WPF 通过 DrawingContext DrawImage 绘制图片 以及更复杂的绘制逻辑请看 博客导航

完成绘制之后,可使用 RenderTargetBitmap 与 BitmapEncoder 配合,将绘制的内容写入到本地图片文件里面

创建 RenderTargetBitmap 对象,给定尺寸,代码如下

    // 画布大小
    var drawingBounds = drawingVisual.Drawing.Bounds;
    // 修改为固定的尺寸
    drawingBounds = new Rect(0, 0, 1024, 768);
    var renderTargetBitmap = new RenderTargetBitmap((int) drawingBounds.Width, (int) drawingBounds.Height, 96, 96, PixelFormats.Pbgra32);

以上代码里面的画布大小有多个选项,一个就是使用绘制的范围,绘制的范围里面可能控制性比较差,因为会受到本身绘制的影响,可能存在绘制范围超过了预期画布尺寸,导致了输出的图片偏差。设置固定的尺寸大小,可以固定画布的尺寸,相对来说比较常用

以上代码里面的 RenderTargetBitmap 的 96 指的是图片的 DPI 值,默认情况下给 96 是比较符合视觉预期的。这里的 DPI 不是屏幕的 DPI 值,一般不应该根据当前的显示设备的 DPI 值赋值给到图片上,应该一直保持是 96 的 DPI 值。这部分有一些前置的知识,更多还请自行查阅 DPI 相关知识

将刚才绘制完成的 DrawingVisual 在 RenderTargetBitmap 渲染出来,代码如下

    renderTargetBitmap.Render(drawingVisual);

现在已经拿到了 RenderTargetBitmap 对象,由于 RenderTargetBitmap 类型继承自 BitmapSource 类型,因此这里可以认为已经拿到了 BitmapSource 对象

现在的 BitmapSource 对象还在内存里面,想要将 BitmapSource 存放为图片文件需要经过图片编码步骤,将编码之后的数据写入到文件才能完成保存图片文件的保存

图片编码可使用 BitmapEncoder 类型的对象进行编码,常用的继承自 BitmapEncoder 的 PngBitmapEncoder 或 JpegBitmapEncoder 等等类型。本文这里通过 PngBitmapEncoder 编码出 png 文件,代码如下

    var pngBitmapEncoder = new PngBitmapEncoder();
    pngBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

    var file = "1.png";

    using (var fileStream = File.Create(file))
    {
        pngBitmapEncoder.Save(fileStream);
    }

通过以上方法即可将图片编码保存到 1.png 文件

使用本文以上的方法即可简单从控制台开始,使用 WPF 辅助绘制内容,将绘制的内容编码为图片文件保存到本地文件

本文以上代码都写在一个 Program.cs 文件里,代码非常简单

using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
var thread = new Thread(() =>
{
    var application = new Application();
    application.Startup += Application_Startup;
    application.Run();
});

void Application_Startup(object sender, StartupEventArgs e)
{
    var drawingVisual = new DrawingVisual();
    using (var drawingContext = drawingVisual.RenderOpen())
    {
        drawingContext.DrawRectangle(Brushes.Black, pen: null, new Rect(0, 0, 1024, 768));
    }

    // 画布大小
    var drawingBounds = drawingVisual.Drawing.Bounds;
    // 修改为固定的尺寸
    drawingBounds = new Rect(0, 0, 1024, 768);
    var renderTargetBitmap = new RenderTargetBitmap((int) drawingBounds.Width, (int) drawingBounds.Height, 96, 96, PixelFormats.Pbgra32);
    renderTargetBitmap.Render(drawingVisual);

    var pngBitmapEncoder = new PngBitmapEncoder();
    pngBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

    var file = "1.png";

    using (var fileStream = File.Create(file))
    {
        pngBitmapEncoder.Save(fileStream);
    }
}

thread.SetApartmentState(ApartmentState.STA);
thread.Start();

本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 1b8661bdbea21fbef432856ddc26999505144ba2

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 1b8661bdbea21fbef432856ddc26999505144ba2

获取代码之后,进入 BayheelearchachearJobarhearne 文件夹,即可获取到源代码

更多 WPF 基础绘图请参阅 博客导航文章来源地址https://www.toymoban.com/news/detail-858580.html

到了这里,关于WPF 基础绘图 创建和加工图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF 性能优化-高刷新绘图

    笔者之前接到一个需求,需要在WPF上实时显示病人实时的生理信号(心电图等)。团队开发,需求很快做完了(Unit test 效果图如下) 但是后来发布到产品上发现,资源占用比本机的要大。本地监控后,发现随着时间推移内存和Page Faults 都在增长,如果在产品上长期(几个月甚至

    2024年02月04日
    浏览(37)
  • C# WPF上位机开发(键盘绘图控制)

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         在软件开发中,如果存在canvas图像的话,一般有几种控制方法。一种是鼠标控制;一种是键盘控制;还有一种是定时器控制。定时器控制,多常见动画、游戏、3d视频当中。而鼠标控制

    2024年02月02日
    浏览(40)
  • 工具系列(九) 本文(2万字) | 在ubuntu中安装docker教程 | 在Linux下Docker将镜像导出 | 上传至服务器 | 部署并创建容器 |

    点击进入专栏: 《人工智能专栏》 Python与Python | 机器学习 | 深度学习 | 目标检测 | YOLOv5及其改进 | YOLOv8及其改进 | 关键知识点 | 各种工具教程

    2024年01月19日
    浏览(74)
  • 春眠不觉晓,Java数据类型知多少?基础牢不牢看完本文就有数了

    文编|JavaBuild 哈喽,大家好呀!我是JavaBuild,以后可以喊我鸟哥!俺滴座右铭是不在沉默中爆发,就在沉默中灭亡,一起加油学习,珍惜现在来之不易的学习时光吧,等工作之后,你就会发现,想学习真的需要挤时间,厚积薄发啦! 我们知道Java是面向对象的静态型编程语言,

    2024年02月02日
    浏览(38)
  • CentOS中创建和删除Bond详细步骤

    1、查看网卡信息 2、设置bond 3、将网卡绑定bond 4、手动创建bonding.conf配置文件,并将其加入系统启动项 此步骤一定要操作,否则bond创建完成后不一会就自动消失了! 5、重启网络服务,加载bond信息 6、查看bond中的网卡 7、查看bond网卡配置和bond信息 1、将网卡从bond中删除 2、

    2024年02月12日
    浏览(38)
  • 【小程序图片水印】微信小程序图片加水印功能 canvas绘图

    感觉有用的话,可以打赏一把么?一毛不嫌少,十块不嫌多 更多详细代码请关注公众号索取(备注:公众号):

    2024年04月29日
    浏览(48)
  • 本文通过实例介绍了Redis的基础知识、数据类型、数据结构以及典型应用场景 值得一看!

    作者:禅与计算机程序设计艺术 2017年,Redis是基于MIT许可发布的一个开源的高性能键值数据库,其开发语言为C语言。它提供了多种数据类型(strings、hashes、lists、sets、sorted sets等),分布式支持(可横向扩展),内存存储,持久化功能,事务处理功能等。作为一种高性能的

    2024年02月06日
    浏览(66)
  • WPF按钮添加图片

    WPF Button添加图片 0、更改模板 效果: 代码: 1、原生态 效果: 代码:  2、去边框图片按钮 示意图: 自定义控件源码 xaml cs 使用源码: 3、纯文字按钮 效果图: 自定义控件 XAML CS 使用:

    2024年02月06日
    浏览(37)
  • 【论文写作】PPT绘图并另存为高清图片

    默认情况下,要另存为图片的 PowerPoint 幻灯片的导出分辨率为每英寸 96 点 (dpi)。 若要更改导出分辨率,请执行以下步骤: 1.退出所有 Windows 程序。 2.右键单击“开始”,然后选择“运行”。 (Win+R) 3.在“打开”框中,键入“regedit”, 然后选择“确定”。 4.根据你使用的

    2024年02月04日
    浏览(42)
  • WPF 设置图片圆角的3种方式

    在WPF中,设置页面布局的时,遇到了设置图片圆角问题,试了以下几种方式,都能实现: 第一种:这种图片是跟着border设置的圆角而改变的,自适应图片的大小 Border x:Name=\\\"b_IsChecked\\\"  Width=\\\"48\\\" Height=\\\"48\\\" HorizontalAlignment=\\\"Right\\\" VerticalAlignment=\\\"Top\\\" CornerRadius=\\\"0,8,0,0\\\" Border.Background Im

    2024年02月10日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包