【SkiaSharp绘图11】SKCanvas属性详解

文章目录

  • SKCanvas
  • 构造SKCanvas
    • 构造光栅 Surface
    • 构造GPU Surface
    • 构造PDF文档
    • 构造XPS文档
    • 构造SVG文档
    • SKNoDrawCanvas
  • 变换
  • 剪裁和状态
  • 构造函数
  • 相关属性
    • DeviceClipBounds获取裁切边界(设备坐标系)
    • ClipRect修改裁切区域
    • IsClipEmpty当前裁切区域是否为空
    • IsClipRect裁切区域是否为矩形
    • LocalClipBounds获取裁切边界(本地坐标系)
    • SaveCount 状态记数
    • TotalMatrix 变换矩阵
    • 示例

SKCanvas

用于在位图、表面或其他绘图设备上执行 2D 图形操作。

  1. 绘图操作

    • SKCanvas 提供了丰富的绘图方法,如绘制几何图形(圆形、矩形、路径等)、文本、位图等。
    • 可以设置画笔(SKPaint)的颜色、样式、线宽等属性,实现各种绘制效果。
  2. 图像合成和组合

    • 可以将多个绘图操作合成为单个图像,支持透明度和混合模式,实现复杂的图形效果。
    • 支持在不同图层上进行绘制,并可以进行图层的合并和组合。
  3. 处理和转换

    • 支持坐标变换(平移、旋转、缩放等),方便实现复杂的图形变换和动画效果。
    • 可以通过剪切区域(ClipRectClipPath)限制绘制区域,优化绘制性能。
  4. 跨平台支持

    • SkiaSharp 是跨平台的,可以在 Windows、macOS、Linux 和移动平台(Android、iOS)上使用,SKCanvas 提供了统一的绘图 API。
  5. 高性能渲染

    • SkiaSharp 使用 GPU 加速和多线程优化,能够高效地处理大规模的图形渲染和复杂的图形操作。

构造SKCanvas

构造光栅 Surface

光栅后端绘制到内存块。该内存可由SkiaSharp或客户端自行管理。
默认推荐使用管理绘制画布命令的内存的对象SKSurface。
OnPaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintGLSurfaceEventArgs e)事件中e参数的Surface就是SKSurface对象。
可通过SKSurface.Create方法的不同参数创建由SkiaSharp或自行管理内存的SKSurface对象。

  1. 由SkiaSharp管理
var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);var info = new SKImageInfo(400, 300);
//通过SKSurface获取Canvas
using (var skSurface = SKSurface.Create(info))
using (var skCanvas = skSurface.Canvas)
using (var skPaint = new SKPaint())
{skPaint.TextSize = 18;skPaint.Color = SKColors.LightGreen;skPaint.IsStroke = true;skCanvas.DrawRect(100, 100, 250, 100, skPaint);skCanvas.DrawText($"SKSurface1", 0, 200, skPaint);canvas.DrawSurface(skSurface, 0, 0, skPaint);
}
  1. 自动分配内存
var info2 = new SKImageInfo(400, 400);
//自行分配内存
var memory = Marshal.AllocCoTaskMem(info2.BytesSize);try
{using (var surface2 = SKSurface.Create(info2, memory, info2.RowBytes))using (var canvas2 = surface2.Canvas)using (var paint = new SKPaint()){paint.Color = SKColors.Blue;paint.TextSize = 18;canvas2.DrawCircle(200, 200, 100, paint);canvas2.DrawText($"SKSurface2", 0, 200, paint);canvas.DrawSurface(surface2, 0, 350, paint);}
}
finally
{Marshal.FreeCoTaskMem(memory);
}

SKSurface.Create
在测试的过程,一开始不知为什么会出现两个矩形,还以为是SkiaSharp的BUG,后不知怎么搞的,又没事了…

构造GPU Surface

GPU Surface必须有一个GRContext对象来管理GPU上下文以及纹理和字体的相关缓存。
GRContext对象与OpenGL上下文或Vulkan设备一一匹配。
如果使用SKGLControl控件,默认的的e.Surface.Context就是启用了GPU的OpenGL

构造PDF文档

使用SkiaSharp直接绘制并生成PDF文档(不支持显示PDF)
PDF后端使用SKDocument而不是SKSurface,因为文档必须包含多个页面。

var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);using (FileStream stream = new FileStream(@"Images\test.pdf", FileMode.CreateNew, FileAccess.Write))
using (var doc = SKDocument.CreatePdf(stream, 72))
using (var pdfCanvas = doc.BeginPage(600, 800))
using (var paint = new SKPaint())
{paint.Color = SKColors.LightGreen;paint.IsAntialias = true;paint.TextSize = 24;pdfCanvas.DrawText("Create PDF Doc by SkiaSharp", 20, 30, paint);pdfCanvas.DrawCircle(300, 400, 150, paint);doc.EndPage();doc.Close();
}
  1. 创建一个写的文件流
  2. 根据文件流和DPI创建SKDocument对象
  3. 根据SKDocument对象创建SKCanvas
  4. 可以SKCanvas绘制内容,生成PDF。

SKDocument.CreatePdf

构造XPS文档

与构造Pdf类似,用SKDocument.CreateXps

var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);using (FileStream stream = new FileStream(@"Images\test.xps", FileMode.Create, FileAccess.Write))
using (var doc = SKDocument.CreatePdf(stream, 72))
using (var pdfCanvas = doc.BeginPage(600, 800))
using (var paint = new SKPaint())
{paint.Color = SKColors.LightGreen;paint.IsAntialias = true;paint.TextSize = 24;pdfCanvas.DrawText("Create XPS doc by SkiaSharp", 20, 30, paint);pdfCanvas.DrawCircle(300, 400, 150, paint);doc.EndPage();doc.Close();
}

在这里插入图片描述

构造SVG文档

使用SKSvgCanvas构造SVG文档。

using (FileStream stream = new FileStream(@"Images\test.svg", FileMode.Create, FileAccess.Write))
using (var svgCanvas = SKSvgCanvas.Create(new SKRect(0, 0, 600, 800), stream))
using (var paint = new SKPaint())
{paint.Color = SKColors.LightGreen;paint.IsAntialias = true;paint.TextSize = 24;svgCanvas.DrawText("Create SVG doc by SkiaSharp", 20, 30, paint);svgCanvas.DrawCircle(300, 400, 150, paint);
}

SKSvgCanvas.Create

SKNoDrawCanvas

构造不绘制的画布,是提供一个“无操作”的画布,这意味着它不会进行任何实际的绘图操作。一般用于性能测试、绘图命令的记录与分析、避免不必要的绘图。

变换

SKCanvas提供Scale、Skew、Translate、RotateDegrees、RotateRadians等常用的二维变换。
还可以使用SetMatrix指定变换矩阵。
使用ResetMatrix可重置矩阵状态。

剪裁和状态

可使用变换矩阵的Save方法来保存当前变换状态,然后使用Restore或RestoreToCount方法恢复以前的状态。还有SaveLayer方法。

构造函数

public SKCanvas (SkiaSharp.SKBitmap bitmap);

创建一个画布,其中包含要绘制的指定位图。

相关属性

DeviceClipBounds获取裁切边界(设备坐标系)

public SkiaSharp.SKRectI DeviceClipBounds { get; }

获取当前裁切边界(在设备坐标中)。

ClipRect修改裁切区域

public void ClipRect (SkiaSharp.SKRect rect, SkiaSharp.SKClipOperation operation = SkiaSharp.SKClipOperation.Intersect, bool antialias = false);

修改当前裁切区域

IsClipEmpty当前裁切区域是否为空

public bool IsClipEmpty { get; }

判断当前裁切区域是否为空。

IsClipRect裁切区域是否为矩形

public bool IsClipRect { get; }

判断当前裁切区域是否为矩形。

LocalClipBounds获取裁切边界(本地坐标系)

public SkiaSharp.SKRect LocalClipBounds { get; }

获取当前的裁切边界(本地坐标系中,矩阵变换后的)

SaveCount 状态记数

public int SaveCount { get; }

获取画布私有堆栈上的矩阵/裁切状态的数量。
当调用SKCanvas对象的Save()方法时,加1。调用Restore()时,减1。
一个新的画布的SaveCount为1。

TotalMatrix 变换矩阵

public SkiaSharp.SKMatrix TotalMatrix { get; }

获取当前画布的变换矩阵。

示例

var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);
using (var paint = new SKPaint())
{paint.Color = SKColors.Red;paint.IsAntialias = true;paint.TextSize = 24;var yOffset = 50F;if (canvas.GetDeviceClipBounds(out var rect)){canvas.DrawText($"DeviceClipBounds:{rect}", 20, yOffset, paint);}yOffset += paint.FontSpacing;rect = new SKRectI(25, 20, 800, 800);//设置裁切区域canvas.ClipRect(rect);canvas.DrawText($"ClipRect:{rect}", 20, yOffset, paint);yOffset += paint.FontSpacing;if (canvas.GetDeviceClipBounds(out rect)){canvas.DrawText($"DeviceClipBounds:{rect}", 20, yOffset, paint);yOffset += paint.FontSpacing;}canvas.DrawText($"IsClipEmpty:{canvas.IsClipEmpty}", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.DrawText($"IsClipRect:{canvas.IsClipRect}", 50, yOffset, paint);yOffset += paint.FontSpacing;rect = SKRectI.Create(100, 50);canvas.DrawText($"ClipRect:{rect} Difference", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.ClipRect(rect, SKClipOperation.Difference);canvas.DrawText($"IsClipRect:{canvas.IsClipRect}", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.DrawText($"LocalClipBounds:{canvas.LocalClipBounds}", 50, yOffset, paint);yOffset += paint.FontSpacing;// 设置画布变换(如平移)canvas.Translate(50, 50);canvas.DrawText($"Translate(50, 50)", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.DrawText($"LocalClipBounds:{canvas.LocalClipBounds}", 50, yOffset, paint);yOffset += paint.FontSpacing;if (canvas.GetDeviceClipBounds(out rect)){canvas.DrawText($"DeviceClipBounds:{rect}", 50, yOffset, paint);yOffset += paint.FontSpacing;}canvas.DrawText($"SaveCount:{canvas.SaveCount}", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.Save();canvas.DrawText($"Call Save()", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.DrawText($"SaveCount:{canvas.SaveCount}", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.Restore();canvas.DrawText($"Call Restore()", 50, yOffset, paint);yOffset += paint.FontSpacing;canvas.DrawText($"SaveCount:{canvas.SaveCount}", 50, yOffset, paint);yOffset += paint.FontSpacing;using (var newCanvas = new SKCanvas(new SKBitmap())){canvas.DrawText($"new SKCanvas SaveCount:{newCanvas.SaveCount}", 50, yOffset, paint);yOffset += paint.FontSpacing;}var matrix = canvas.TotalMatrix;canvas.DrawText($"TotalMatrix:{string.Join(",",matrix.Values)}", 50, yOffset, paint);yOffset += paint.FontSpacing;
}

SKCanvas属性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/35888.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JFreeChart 生成Word图表

文章目录 1 思路1.1 概述1.2 支持的图表类型1.3 特性 2 准备模板3 导入依赖4 图表生成工具类 ChartWithChineseExample步骤 1: 准备字体文件步骤 2: 注册字体到FontFactory步骤 3: 设置图表具体位置的字体柱状图:饼图:折线图:完整代码&#x…

国产车规MCU OTA方案总结

目录 1. 旗芯微FC4150 OTA 2. 云途YTM32B1MD OTA 3.小结 今天没有废话,啪一下很快,把目前接触到的国内带eFlash的车规MCU硬件OTA方案做一个梳理。 1. 旗芯微FC4150 OTA 旗芯微FC4150是基于ARM Cortex(快去审核下官网介绍,少了个T)-M4F内…

openGauss Developer Day 2024丨MogDB实现数据库技术跨越,Ustore引擎革新存储新境界

openGauss Developer Day 2024 6月21日,openGauss Developer Day 2024在北京昆泰嘉瑞文化中心成功召开。大会聚集学术专家、行业用户、合作伙伴和开发者,共同探讨数据库面向多场景的技术创新,分享基于 openGauss 的行业联合创新成果及实践案例…

探索PHP中的魔术常量

PHP中的魔术常量(Magic Constants)是一些特殊的预定义常量,它们在不同的上下文中具有不同的值。这些常量可以帮助开发者获取文件路径、行号、函数名等信息,从而方便调试和日志记录。本文将详细介绍PHP中的魔术常量,帮助…

web前端——javaScript

目录 一、javaScript概述 1.javaScript历史 2.JavaScript与html,css关系 二、基本语法 ①放在head中 ②放在 body中 ③写在外部的.js文件中 1.变量 2.数据类型 3.算术运算符 4.逻辑运算符 5.赋值运算 6.逻辑运算符 7.条件运算符 8.控制语句 三、函数 1…

Arduino - 按钮 - 长按短按

Arduino - Button - Long Press Short Press Arduino - 按钮 - 长按短按 Arduino - Button - Long Press Short Press We will learn: 我们将学习: How to detect the button’s short press 如何检测按钮的短按How to detect the button’s long press 如何检测…

重大进展!微信支付收款码全场景接入银联网络

据中国银联6月19日消息,近日,银联网络迎来微信支付收款码场景的全面接入,推动条码支付互联互通取得新进展,为境内外广大消费者提供更多支付选择、更好支付体验。 2024年6月,伴随微信支付经营收款码的开放,微…

Rust: duckdb和polars读csv文件比较

一、文件准备 样本内容,N行9列的csv标准格式,有字符串,有浮点数,有整型。 有两个csv文件,一个大约是2.1万行;一个是64万行。 二、toml文件 [package] name "my_duckdb" version "0.1.0&…

VSCode安装OpenImageDebugger

VSCode安装OpenImageDebugger 1. 官网2. 编译2.1 依赖项2.2 编译 OpenImageDebugger2.3 配置 GDB 和 LLDB 3. 验证安装是否成功 1. 官网 下载路径:OpenImageDebugger 2. 编译 2.1 依赖项 官网上描述, Qt 5.15.1Python 3.10.12 这两个其实配置并不需…

图解HTTP笔记整理(前六章)

图解HTTP 第一章 web使用HTTP (HyperText Transfer Protocol,超文本传输协议)协议作文规范,完成从客户端到服务器端等一系列运作流程。 协议:计算机与网络设备要相互通信,双方就必须基于相同的方法。比如…

【论文阅读】--Popup-Plots: Warping Temporal Data Visualization

弹出图:扭曲时态数据可视化 摘要1 引言2 相关工作3 弹出图3.1 椭球模型3.1.1 水平轨迹3.1.2 垂直轨迹3.1.3 组合轨迹 3.2 视觉映射与交互 4 实施5 结果6 评估7 讨论8 结论和未来工作致谢参考文献 期刊: IEEE Trans. Vis. Comput. Graph.(发表日期: 2019&…

HQChart使用教程30-K线图如何对接第3方数据41-分钟K线叠加股票增量更新

HQChart使用教程30-K线图如何对接第3方数据40-日K叠加股票增量更新 叠加股票叠加分钟K线更新Request 字段说明Data.symbol 协议截图返回json数据结构overlaydata HQChart代码地址交流 叠加股票 示例地址:https://jones2000.github.io/HQChart/webhqchart.demo/samples/kline_i…

可以一键生成热点营销视频的工具,建议收藏

在当今的商业环境中,热点营销已经成为了一种非常重要的营销策略。那么,什么是热点营销呢?又怎么做热点营销视频呢? 最近高考成绩慢慢公布了,领导让结合“高考成绩公布”这个热点,做一个关于企业或产品的营销…

鸿蒙NEXT开发:工具常用命令—install

安装三方库。 命令格式 ohpm install [options] [[<group>/]<pkg>[<version> | tag:<tag>]] ... ohpm install [options] <folder> ohpm install [options] <har file> alias: i 说明 group&#xff1a;三方库的命名空间&#xff0c;可…

sys.stdin对象——实现标准输入

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 sys.stdin是一个标准化输入对象&#xff0c;可以连续输入或读入文件所有内容&#xff0c;不结束&#xff0c;不能直接使用。输入完成后&am…

print()函数——打印输出

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 print()函数是Python编程最常见的函数&#xff0c;常用于输出程序结果&#xff0c;默认输出到屏幕&#xff0c;也可以输出到指定文件。 语法参考 pr…

吉他谱制作软件哪个好 吉他弹唱谱制作软件推荐

在市面上存在着多种吉他谱制作软件&#xff0c;如何选择一款适合自己需求的软件成为了许多人面临的挑战。下面来看看吉他谱制作软件哪个好&#xff0c;吉他弹唱谱制作软件推荐的相关内容。 一、吉他谱制作软件哪个好 吉他谱制作软件在现代音乐创作中扮演着重要角色&#xff0c…

调频信号FM的原理与matlab与FPGA实现

平台&#xff1a;matlab r2021b&#xff0c;vivado2023.1 本文知识内容摘自《软件无线电原理和应用》 调频(FM)是载波的瞬时频率随调制信号成线性变化的一种调制方式&#xff0c;音频调频信号的数学表达式可以写为&#xff1a; Fm频率调制&#xff0c;载波的幅度随着调制波形…

open()函数——打开文件并返回文件对象

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 open()函数用于打开文件&#xff0c;返回一个文件读写对象&#xff0c;然后可以对文件进行相应读写操作。 语法参考 open()函数的语法格式如下&…

【K8s】专题六(2):Kubernetes 稳定性之健康检查

以下内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01;如果对您有帮助&#xff0c;烦请点赞、关注、转发&#xff01;欢迎扫码关注个人公众号&#xff01; 目录 一、基本介绍 二、工作原理 三、探针类型 1、存活探针&#xff08;LivenessProbe&#x…