首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在Skia中将画布原点设置为左下角

在Skia图形库中,画布的原点默认位于左上角。如果你希望将原点设置在左下角,可以通过对画布进行坐标变换来实现。以下是实现这一目标的基础概念和相关步骤:

基础概念

  1. 坐标系:在计算机图形学中,坐标系定义了点的位置。常见的坐标系有笛卡尔坐标系,其中原点是 (0, 0),x 轴向右增加,y 轴向上增加。
  2. 坐标变换:通过矩阵运算改变图形的坐标系,包括平移、旋转、缩放等。

实现步骤

要将Skia中的画布原点设置为左下角,你需要执行以下步骤:

  1. 创建画布:首先创建一个Skia画布。
  2. 应用变换:使用Skia的变换矩阵将画布的原点从左上角移动到左下角。

示例代码

以下是一个简单的示例代码,展示了如何在Skia中将画布原点设置为左下角:

代码语言:txt
复制
#include "include/core/SkCanvas.h"
#include "include/core/SkSurface.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkRect.h"
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"

void draw(SkCanvas* canvas) {
    // 创建一个红色的画笔
    SkPaint paint;
    paint.setColor(SK_ColorRED);
    paint.setStyle(SkPaint::kFill_Style);

    // 获取画布的尺寸
    SkRect bounds = canvas->getLocalBounds();

    // 在左下角绘制一个矩形
    canvas->drawRect(SkRect::MakeXYWH(0, bounds.height(), 100, 100), paint);
}

int main() {
    // 创建一个100x100的画布
    const int width = 100;
    const int height = 100;
    SkImageInfo imageInfo = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
    sk_sp<SkSurface> surface(SkSurface::MakeRaster(imageInfo));
    SkCanvas* canvas = surface->getCanvas();

    // 应用变换,将原点移动到左下角
    canvas->concat(SkMatrix::MakeScale(1, -1)); // 垂直翻转
    canvas->translate(0, -height); // 平移

    // 绘制图形
    draw(canvas);

    // 保存结果到文件(可选)
    sk_sp<SkImage> image(surface->makeImageSnapshot());
    if (image) {
        sk_sp<SkData> data(image->encodeToData(SkEncodedImageFormat::kPNG, 100));
        if (data) {
            SkFILEWStream("output.png").write(data->data(), data->size());
        }
    }

    return 0;
}

解释

  1. 创建画布:使用 SkSurface::MakeRaster 创建一个100x100的画布。
  2. 应用变换
    • SkMatrix::MakeScale(1, -1) 进行垂直翻转,使y轴方向反转。
    • canvas->translate(0, -height) 将画布向上平移 height 个单位,使得原点移动到左下角。
  • 绘制图形:在变换后的坐标系中绘制一个矩形。

应用场景

这种变换在需要以左下角为原点的应用中非常有用,例如:

  • 地图应用:地图通常以左下角为原点。
  • 游戏开发:某些游戏引擎或场景可能需要左下角为原点。
  • 图形设计软件:某些设计工具默认以左下角为原点。

通过这种方式,你可以灵活地调整坐标系,以适应不同的应用需求。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

在C#中将未使用的对象设置为 NULL 的好处

今天,咱们来探讨一个有趣却颇具争议的话题:在C#中,我们是否应该将未使用的对象设置为null呢?...将对象设置为NULL能否释放内存? 咱们先来破除这个误区:答案是否定的。 在C#中,垃圾回收器(Garbage Collector,简称GC)负责自动管理内存,确保未使用的对象能被回收。...手动将它们设置为null可确保在不再需要它们时能及时回收。 这只是其中一个好处。 你有没有考虑过这样一种场景:假设有一个类A,它包含一个静态变量aa。当类A被垃圾回收时,静态变量aa会随之被释放吗?...将一个对象设置为null可能会引发NullReferenceException(空引用异常),尤其是在多线程环境中。 想象一下,如果多个线程正在访问同一个对象,而其中一个线程将它设置为了null。...将未使用的对象设置为null有其特定的用途和好处,但在大多数情况下,不这么做也不会产生重大的负面影响。最好根据具体的需求和场景来决定是否要将对象设置为null。

4200
  • webgl实现径向模糊

    因此,实现径向模糊的大致流程如下: 确定径向模糊的中心点,一般为画布的中心点,或这个某个对象的中心点在屏幕投影所在的位置。(注意中心点是2维坐标) 计算当前像素和中心点的距离和向量线段。...本示例中将对动态的图像施加效果。先上一张图看看效果: image.png 首先绘制的几个圆环对象,然后对绘制的图像施加径向模糊。...在此示例中,缩放的中心点设置为画布的中心。 画布的大小为512像素,因此上面的代码相应地声明了一些常量。 vec2变量centerOffset用于定义中心位置。...画布的坐标。...注意gl_FragCoord坐标的原点是在左下角,而canvas画布的坐标原点在左上角,应此做了一个翻转计算: 512.0 - gl_FragCoord.t 计算变量fcc,表示当前坐标到中心点的向量。

    1.5K31

    OpenGL ES Shader 怎样绘制一颗“心”

    心形绘制可以参考 ShaderToy 上的代码: https://www.shadertoy.com/view/XsfGRn 上述代码绘制心形,首先将原点从左下角移至坐标系中央,这样所有片元的向量均以屏幕中心为起点...,则向量 uv 就是画布中心与像素点坐标之间的方向向量。...vec2 uv = (2.0 * fragCoord - iResolution.xy) / min(iResolution.y,iResolution.x); //坐标原点设置到中心位置 然后利用反正切函数值和当前片元...fragCoord) { vec2 uv = (2.0 * fragCoord - iResolution.xy) / min(iResolution.y,iResolution.x); //坐标原点设置到中心位置..., d); vec3 color = vec3(col) * vec3(1.0, 0.0, 0.0); fragColor = vec4(color,1.0); } 函数曲线实际上是把整个画布当做一个原点位于中心坐标系

    45420

    dotnet OpenXML 使用 MAUI 渲染 PPT 的面积图图表

    在 MAUI 里,绘制线条只需要使用 DrawLine 方法,传入两个点即可。控制线条的粗细和颜色等,是通过在 DrawLine 方法之前,先设置好参数属性。...按照 Path 的创建惯例,开始点采用 Move 方法设置,如以下代码 path.Move(startX, startY); 在 MAUI 的设计里,可以使用连续的方法,输入绘制参数,如画两条线,然后设置几何关闭...如本文开始的开发架构图所述,在 Windows 上通过 Microsoft.Maui.Graphics.Skia 将 Skia 和 MAUI 对接,使用 Skia 作为 MAUI 的画布,在绘制完成之后使用...Render 方法里,将先创建 Skia 的画布,接着使用 Skia 的画布创建 MAUI 的画布,将 MAUI 的画布传入到委托作为参数,绘制完成保存本地文件 在 Skia 里面,最重要的概念是画布...的窗口 根据上文的 WPF 对接 Skia 和 MAUI 的逻辑,可以了解到对接的方式是使用 Skia 的画布创建 MAUI 的 SkiaCanvas 画布,如以下代码 // the the canvas

    2.1K30

    自定义View概述

    Flutter架构图 和Flutter自带的Wdiget一样,自定义的Widget也会经过Skia被编译成原生代码,所以性能上也是不受影响的。...与绘制相关的知识 ---- 学过前端或者终端开发的童鞋,应该对绘制都比较熟悉,绘制主要还是靠画布canvas和画笔Paint和完成的,画布就是你绘制图形的地方,画笔就是你用来作画的笔。...画布canvas 画布是一个矩形区域,我们可以控制其每一像素来绘制我们想要的内容 canvas 拥有多种绘制点、线、路径、矩形、圆形、以及添加图像的方法,结合这些方法我们可以绘制出千变万化的画面。...虽然,画布可以画这些东西,但是决定这些图形颜色、粗细表现的还是画笔。 画笔Paint Paint非常好理解,就是我们用来画图形的工具,我们可以设置画笔的颜色、粗细、是否抗锯齿、笔触形状以及作画风格。...Flutter中的坐标系 在Flutter中坐标系的坐标原点在左上角,X坐标越往右越大,Y坐标越往下越大 ?

    76031

    canvas 处理图像(上)

    加载图像 canvas 高级功能(下)讲述了如何将画布导出为图像,将它保存到本地和与他人共享。现在,我们将学习如何实现完全相反的操作:将图像加载到画布中。...然后,通过把它的src属性设置为一个有效的图像文件路径,就可以将该图像加载到图像元素中,这就好像是设置了HTML img元素的src属性。...将前一个例子的drawImage方法修改为以下形式,图像就能够被调整为在画布中完全显示:context.drawImage(image, 0, 0, 500, 333); 其中,宽度为500像素,与画布的宽度相等...裁剪是drawImage方法的最后一种用法,它总共有9个参数:源图像、源图像的裁剪区原点坐标(x, y)、源图像的裁剪区宽度和高度、在画布(目标)上绘制图像的原点坐标(x, y)及在画布上绘制图像的宽度和高度...一定要记住,当图像翻转时,原点会转到图像右边,所以你必须移动原点进行补偿,以便从右到左进行绘制。

    2.1K10

    WPF 自己封装 Skia 差量绘制控件

    使用 Skia 能做到在多个不同的平台使用相同的一套 API 绘制出相同界面效果的图片,可以将图片绘制到应用程序的渲染显示里面。...这样的绘制方法显然效率不够高 在上一篇博客里面告诉大家如何在 WPF 中使用 Skia 绘制,请看 WPF 使用 Skia 绘制 WriteableBitmap 图片 而这样的绘制方式意味着每次都需要重新绘制画布...只是稍微有点 在使用 WriteableBitmap 作为 Skia 的承载,就需要再来一步,让 WriteableBitmap 在界面绘制。...SkiaCanvas 控件的时候,需要先设置他的宽度和高度,也不支持后续更改哈 在创建完成了 SKSurface 字段,就可以通过调用他的绘制方法在 WriteableBitmap 上绘制内容。...或者换句话说,这里的绘制逻辑有坑在于不能做到对准界面更新 上面这个方法是提供差量更新的,也就是每次绘制的内容都会在上一次画布的基础上继续绘制 下面写一点代码试试,在鼠标划过应用时,绘制出鼠标划过的点,将这些点连为线

    1.1K30

    零基础学编程041:欧拉公式的几何意义

    第1项:iπ ,把其中的 i 理解为逆时针旋转90度,这样就是在垂直方向上前进 π 个单位。 第2项,再旋转90度,前进 (π*π / 2) 个单位。...in range(1,17) : turtle.left(90) turtle.forward((math.pi ** i) / math.factorial(i)) 这里小海龟的默认画布是以像素为单位的...,前进1、2个像素看不出效果,需要把画布的坐标范围设置一下,在图形世界里称为世界坐标系。...下面的语句表示画布的左下角坐标是(-5,-5),右上角坐标是(5,5): setworldcoordinates(-5, -5, 5, 5) 最后的代码是这样的: import turtle import...turtle.left(90) turtle.forward((math.pi ** i) / math.factorial(i)) 我加上了坐标系和两个参考点,最后的图形是这样的: 小海龟从原点出发

    2.5K90

    从 QuickJS 到 Dart VM:稿定跨端渲染工程的运行时演化

    最终的 JS 版本架构可以分三层概括如下: 基础的画布绘制能力依赖 Skia。我们参考了 Flutter Engine 源码中的 Layer 结构,封装出可树形嵌套的 Layer 类。...画布外的常规 UI 控件使用平台原生,如各种滑杆、按钮、面板等。...如果基于该能力来复用 Flutter 中的 Dart VM,那么就可以获得相当简单而统一的应用层技术栈: 画布中的内容用 Skia 自行渲染,并包装成 Dart 中的 Layer 类来使用。...在具备支持离屏绘制的 Skia 实例后,就可以用 C++ 的 Layer 来绘制它,进而为 Layer 绑定 Dart 对象了。...这类 API 具有 _DL 后缀,可以用来在 C++ 中将普通的 Dart_Handle 转换为具备长生命周期的 Dart_PersistentHandle、Dart_WeakPersistentHandle

    2.5K31

    Flutter 2 源码阅读

    渲染层 Rendering 是在 ::dart:ui 库之上的第一个抽象层,它为你做了所有繁重的数学工作。为了做到这一点,它使用 RenderObject 对象,该对象是真正绘制到屏幕上的渲染对象。...2)、Engine:Engine 使用 C++ 实现,主要包括:Skia,Dart 和 Text。Skia 是开源的二维图形库,提供了适用于多种软硬件平台的通用 API。...在安卓上,系统自带了 Skia,在 iOS 上,则需要 APP 打包 Skia 库,这会导致 Flutter 开发的 iOS 应用安装包体积更大。...3)、Embedder:Embedder 是一个嵌入层,即把 Flutter 嵌入到各个平台上去,这里做的主要工作包括渲染 Surface 设置,线程设置,以及插件等。...从这里可以看出,Flutter 的平台相关层很低,平台(如 iOS)只是提供一个画布,剩余的所有渲染相关的逻辑都在 Flutter 内部,这就使得它具有了很好的跨端一致性。

    50920

    Fabric.js 缩放画布 🍬

    使用 canvas 开发的项目,滚轮缩放画布的需求应该不算少数,比如地图。 Fabric.js 也提供了缩放画布的功能,本文主要讲解设置画布大小的几种方法。 动手实现 在动手前先查查文档。...我把和本文相关的文档放在这 mouse:wheel:滚轮事件 getZoom:获取画布当前缩放级别 setZoom:设置画布缩放级别 zoomToPoint:设置画布缩放比例及缩放原点 其中 setZoom...起步 在使用缩放功能之前,先初始化一下画布。 我还会在画布上设置一个背景图,便于观察。...(以左上角为原点) 以左上角为原点进行缩放画布,推荐使用 getZoom 和 setZoom 组合。...getZoom 可以获取画布当前缩放级别,用 setZoom 设置一个新的缩放级别。 所以我在页面上再加2个按钮,一个放大,一个缩小。

    5.8K30

    Unity ugui屏幕适配与世界坐标到ugui屏幕坐标的转换

    为了更直观的了解ugui的缩放原则,我们可以直接通过实验测试数据来观察: 如上所示,此时我设置的测试分辨率为1440*2960,因为设置的是按照参考分辨率的宽度进行匹配,所以整个画布的高度就会变为2960...通过上面的观察我们可以发现,当以宽度进行适配时,只与参考分辨率的宽度和屏幕分辨率的宽度有关,是以这两个数值的比例进行的画布缩放; 同样的道理,如果我们设置为以高度进行匹配,就与屏幕的宽度和参考分辨率的宽度无关了...当然了,如果你坚持再创建一个基于场景中三维空间的画布,那我无话可说,但更好的做法显然是统一在一个二维画布的对应屏幕位置正确显示,这样你每个场景只需要统一管理一个Canvas即可。...返回的值是以屏幕左下角为坐标原点得到的UIPos,因为默认情况下二维屏幕计算坐标轴就是以左下为原点的。...2019年12月26日更新: 更新一个刘海屏的适配方案: 在游戏的全局系统设置中增加可以压缩canvas左右边缘的设置滑条,类似于这样: ?

    2.9K10

    从零打造一个Web地图引擎

    TMS规范:腾讯地图,坐标原点在左下角 WMTS规范:原点在左上角,瓦片不是正方形,而是矩形,这个应该是官方标准 百度地图比较特立独行,投影、分辨率、坐标系都跟其他厂商不一样,原点在经纬度都为0的位置...,非洲边上的海里,而瓦片的原点在左上角: 再来看下图会更容易理解: 3857坐标系的原点相当于在世界平面图的中间,向右为x轴正方向,向上为y轴正方向,而瓦片地图的原点在左上角,所以我们需要根据图上【...(画布默认原点为左上角,x轴正方向向右,y轴正方向向下),也就是把中心经纬度作为坐标原点,那么中心瓦片的显示位置就是这个差值。...知道原因就简单了,首先我们加个缓存对象,因为在拖动过程中,很多瓦片只是位置变了,不需要重新加载,同一个瓦片加载一次,后续只更新它的位置即可;另外再设置一个对象来记录当前画布上应该显示的瓦片,防止不应该出现的瓦片渲染出来...画布默认缩放值为1,放大则在此基础上乘以2倍,缩小则除以2,然后动画到目标值,动画期间设置画布的缩放值及清空画布,重新绘制画布上的已有瓦片,达到放大或缩小的视觉效果,动画结束后再调用renderTiles

    3.9K10

    .NET跨平台绘图基础库--SkiaSharp

    SkiaSharp 是一个跨平台的 2D 图形 API,用于 .NET 平台,基于 Google 的 Skia 图形库。它提供了全面的 2D API,可以在移动、服务器和桌面模型上渲染图像。...终于到了2021年10月12日,.NET 6发布RC2候选版本(正式发布前最后一版),宣布了一个突破性的技术:支持在Web网页上采用SkiaSharp画布绘图。...这是.NET跨平台技术发展的一个创举,使用C#可以直接在网页画布上绘图,打破了JavaScript+canvas的长期垄断地位。...MAUI:在 MAUI 中,Microsoft.Maui.Graphics 和 SkiaSharp 都是重要的库,它们为开发者提供了强大的图形绘制能力。...Uno:SkiaSharp 与 Uno Platform 的比较中,SkiaSharp 被描述为一个跨平台的 2D 图形 API,适用于 .NET 平台,提供了全面的 2D API,可以用于移动、服务器和桌面模型来渲染图像

    7710

    Fabric.js 禁止元素超出画布

    元素的坐标和画布的坐标,都是以左上角为原点。所以【情况1】只需考虑元素的 xy坐标 有没有超过画布的左边和上边。...【情况2】是用元素右边和下边跟画布做比较,而元素的原点是在元素的左上角,所以元素的右边是 元素原点x坐标 + 元素的宽度 ,元素的下边是 元素原点y坐标 + 元素的高度 。...最后得出的公式: 【公式1】超出画布左边:图形左上方x坐标 画布左上方x坐标,将图形的 left 设置成画布左上方x坐标的值。...【公式2】超出画布上边:图形左上方y坐标 画布左上方y坐标,将图形的 top 设置成画布左上方y坐标的值。...我将这时机设置在元素的 mouseup 事件,也就是移动元素后松开鼠标的时刻。

    4.2K30

    SkiaSharp 渲染输出 SVG 文件

    谷歌的 Skia 的一个卖点就是提供了完美的 SVG 的支持,包括输入和输出。输入指的是给一张 SVG 图片,将这个 SVG 渲染出来。输出就是将输出画面保存为 SVG 格式的图片。...自然 SkiaSharp 是 Skia 的封装,也就带上了此功能。...本文将告诉大家如何在 SkiaSharp 里面设置画面输出为 SVG 图片,使用 SkiaSharp 制作和编辑 SVG 图片 如 dotnet 控制台 使用 Microsoft.Maui.Graphics...配合 Skia 进行绘图入门 提供的方法,先新建项目安装必要的库 通过 SKSvgCanvas 提供的 SVG 画板功能进行绘制逻辑,所谓制作和编辑 SVG 图片其实就是在画板里面进行绘制,如对原有的...因此的核心逻辑就是将画布的渲染内容保存为 SVG 图片 创建 SKSvgCanvas 的方法十分简单,需要两个参数,分别是 SVG 的范围和输出的内容,如以下代码 var fileName = $"xx.svg

    1.7K20
    领券