【QML 画布Canvas】2D绘图(下)

本文介绍了如何在QtQuick的Canvas中使用2D绘图功能,包括创建线性渐变、辐射渐变和锥形渐变,并展示了各种示例。此外,还讲解了设置阴影效果的方法以及如何使用图像。最后,探讨了坐标转换,如平移、缩放、旋转和扭曲在Canvas中的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接着上一章的内容,本章继续进行后续画图相关操作。

1、渐变填充

Canvas 支持 3 种渐变:线性渐变、辐射渐变、锥形渐变。

1.1、线性渐变

  • createLinearGradient(real x0, real y0, real x1, real y1),返回一个 CanvasGradient 对象,该对象表示线性渐变,该渐变沿起点(x0,y0)和终点(x1,y1)之间的线过渡颜色;
  • addColorStop 函数添加渐变点;

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

下面看一个示例:

import QtQuick 2.9

Canvas {
    width:120
    height: 120

    onPaint: {
        var ctx = getContext("2d")
        ctx.lineWidth = 2

        var linear = ctx.createLinearGradient(10, 10, 100, 10)
        linear.addColorStop(0, "white")
        linear.addColorStop(0.5, "#FF00FF")
        linear.addColorStop(1, "#333333")
        ctx.fillStyle = linear
        ctx.fillRect(10, 10, 100, 100)
        ctx.strokeRect(10, 10, 100, 100)
    }
}

运行结果如下:

 

1.2、辐射渐变

  • createRadialGradient(real x0, real y0, real r0, real x1, real y1, real r1),返回一个CanvasGradient对象,该对象表示一个辐射渐变,该渐变沿由起始圆(x0,y0)和半径 r0以及终止圆的原点(x1,y1)和半径 r1 给出的圆锥进行绘制。
  • addColorStop 函数添加渐变点;

下面看一个示例:

import QtQuick 2.9

Canvas {
    width:120
    height: 120

    onPaint: {
        var ctx = getContext("2d")
        ctx.lineWidth = 2

        var radial = ctx.createRadialGradient(30, 70, 5, 60, 50, 80)
        radial.addColorStop(0, "white")
        radial.addColorStop(0.5, "#FF00FF")
        radial.addColorStop(1, "#333333")
        ctx.fillStyle = radial
        ctx.fillRect(10, 10, 100, 100)
        ctx.strokeRect(10, 10, 100, 100)
    }
}

1.3、锥形渐变

  • createConicalGradient(real x, real y, real angle),返回一个 CanvasGradient 对象,该对象表示一个圆锥形渐变,该圆锥形渐变围绕中心点(x,y)沿逆时针方向插入颜色,起始角度以弧度为单位。
  • addColorStop 函数添加渐变点;

下面看一个示例:

import QtQuick 2.12

Canvas {
    width:120
    height: 120

    onPaint: {
        var ctx = getContext("2d")
        var conical = ctx.createConicalGradient(60, 60, Math.PI / 4)
        conical.addColorStop(0, "white")
        conical.addColorStop(0.5, "#FF00FF")
        conical.addColorStop(1, "#333333")
        ctx.fillStyle = conicals
        ctx.fillRect(10, 10, 100, 100)
        ctx.strokeRect(10, 10, 100, 100)
    }
}

运行效果如下:

 

2、阴影

  • shadowOffsetX:阴影在 x 轴方向偏移。
  • shadowOffsetY:阴影在 y 轴方向偏移。
import QtQuick 2.9

Canvas {
    width:500
    height: 200

    onPaint: {
        var ctx = getContext("2d")
        ctx.fillStyle = "grey"
        ctx.save()
        ctx.shadowBlur = 20
        ctx.shadowColor = "blue"
        ctx.fillRect(60, 30, 100, 100)
        ctx.restore()
        ctx.save();
        ctx.shadowBlur = 20
        ctx.shadowColor = "green"
        ctx.shadowOffsetX = 15
        ctx.shadowOffsetY = 15
        ctx.fillRect(200, 30, 100, 100)
        ctx.restore()
        ctx.fillRect(350, 30, 100, 100)
    }
}

运行效果如下:

 

3、使用图像

在 Canvas 种可以直接使用已经存在的图形,Context2D 类型提供了 drawImage 函数用于绘制图形,该函数提供 3 个重载版本:

// 1.将 image 绘制在 Canvas 上,图像左上角位于(dx,dy)处
drawImage(variant image, real dx, real dy, real dw, real dh)

// 2.将 image 绘制在矩形(dx,dy,dw,dh)上
drawImage(variant image, real dx, real dy)

// 3.将 image 的矩形(sx,sy,sw,sh)绘制在 Canvas 的矩形(dx,dy,dw,dh)上
drawImage(variant image, real sx, real sy, real sw, real sh, real dx, real dy, real dw, real dh)

下面看一个示例:

import QtQuick 2.9

Rectangle {
    width: 300
    height: 180

    Canvas {
        id: canvas
        anchors.fill: parent
        onImageLoaded: {
            if (canvas.isImageError("http://www.baidu.com/img/bdlogo.gif")) {
                console.log("Image failed to load!")
            }
            var ctx = getContext("2d")
            ctx.drawImage("http://www.baidu.com/img/bdlogo.gif", 0, 0, 270, 129)
            canvas.requestPaint()
        }
    }

    Component.onCompleted: {
        canvas.loadImage("http://www.baidu.com/img/bdlogo.gif")
    }
}

运行效果如下:

 

4、坐标转换

Context2D 提供的图形变换全部是仿射变换:平移、缩放、旋转和扭曲,根据计算机图形学原理,所有的仿射变换都归结于矩阵乘法,Context2D 提供了如下两个函数:

  • setTransform(real a, real b, real c, real d, real e, real f):将转换矩阵更改为参数指定的矩阵,替换旧的变换矩阵;
  • transform(real a, real b, real c, real d, real e, real f):通过将给定的变换矩阵乘以当前矩阵,将其应用于当前矩阵;

二者关联:setTransform(a,b,c,d,e,f)方法实际上将当前变换重置为单位矩阵,然后使用相同的参数调用transform(a,b,c,d,e,f)方法。

HTML Canvas 2D上下文规范将转换矩阵定义为:

 

  • a 是 x 轴方向的缩放因子;
  • c 是 x 轴方向的斜切因子;
  • e 是 x 轴方向的平移因子;
  • b 是 y 轴方向的缩放因子;
  • d 是 y 轴方向的斜切因子;
  • f 是 y轴 方向的平移因子;

比例因子和偏斜因子是倍数; e 和 f 是坐标空间单位,就像平移(x,y)方法中的单位一样。

4.1、平移

使用 translate 函数进行坐标轴的平移,translate(x,y)等价于 transform(1,0,0,1,x,y)。

下面看一个示例:

import QtQuick 2.9

Canvas {
    width: 150
    height: 150

    onPaint: {
        var ctx = getContext("2d")
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("1", 30, 40)
        ctx.translate(70, 60);
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("2", 30, 40)
    }
}

运行效果如下:

 

4.2、缩放

使用 scale 函数进行缩放,scale(x,y)等价于 transform(ax,0,0,by,0,0)。

下面看一个示例:

import QtQuick 2.9

Canvas {
    width: 150
    height: 150

    onPaint: {
        var ctx = getContext("2d")
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("1", 30, 40)
        ctx.translate(70, 0)
        ctx.scale(0.5, 0.5)
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("2", 30, 40)
    }
}

运行效果如下:

 

4.3、旋转

使用 rotate 函数进行旋转,rotate(x)是将坐标轴顺时针旋转 x,等价于 transform(cos(x),sin(x),-sin(x),cos(x),0,0)。

 

旋转后的变换矩阵如下:

 

下面看一个示例:

import QtQuick 2.9

Canvas {
    width: 150
    height: 150

    onPaint: {
        var ctx = getContext("2d")
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("1", 30, 40)
        ctx.translate(100, 0)
        ctx.rotate(Math.PI / 4)
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("2", 30, 40)
    }
}

运行效果如下:

 

4.4、斜切

斜切也就是扭曲,使用 shear 函数进行斜切,shear(x,y)等价于 transform(1,by,cx,1,0,0)。

下面看一个示例:

import QtQuick 2.9

Canvas {
  width: 170
  height: 150

    onPaint: {
        var ctx = getContext("2d")
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("1", 30, 40)
        ctx.translate(70, 0)
        ctx.shear(0.5, 0.5)
        ctx.fillRect(10, 10, 50, 50)
        ctx.strokeText("2", 30, 40)
    }
}

运行效果如下:

 本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值