ArkTS开发系列之导航 (2.6 图形)

上篇回顾:ArkTS开发系列之导航 (2.5.2 页面组件导航)

本篇内容: 显示图片、自定义图形和画布自定义图形的学习使用

一、知识储备

1. 图片组件(Image)

  • 可以展示jpg 、png 、svg 、gif等各格式的网络和本地资源文件图片的组件
  • 接口调用
Image(src: string | Resource | media.PixelMap)
  • 实际代码调用
Image('images/view.jpg').width(200)//ets本次资源目录下
Image('https://www.example.com/example.JPG') // 网络图片实际使用时请替换为真实地址
Image($r('app.media.ic_hm_logo'))//resources/base/media目录下
Image($rawfile('snap'))//resources/rawfile目录下
Image('file://media/Photos/5').width(200)//手机媒体库中图片资源
  • 从手机媒体库中选择图片
//从手机媒体库中选择图片try {let photoSelectOptions = new picker.PhotoSelectOptions(); //媒体库选择器设置photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; //图片类型photoSelectOptions.maxSelectNumber = 5; //最多 选取五张let photoPicker = new picker.PhotoViewPicker; //初始化图片选择器photoPicker.select(photoSelectOptions).then(photoSelectResult => { //选择结果回调this.imgListData = photoSelectResult.photoUris;console.error(`imgListData size is ${this.imgListData.length}`)}).catch(err=>{console.error(`select failed code is ${err.code}, msg : ${err.message}`)})} catch (err) {console.error(`load photo failed ${err.code}, msg: ${err.message}`)}
  • 多媒体像素图
 http.createHttp().request(this.imgUrl, (err, data) => {if (err) {console.error(`err is ${JSON.stringify(err)}`)} else {let code = data.responseCode;if (ResponseCode.ResponseCode.OK == code) {let res: any = data.result;let imageSource = image.createImageSource(res)let options = {alphaTye: 0, //透明度editable: false, //是否可编辑pixelFormat: 3, //像素格式scaleMode: 1, //缩略值size: { height: 100, wight: 100 } //创建图片大小}imageSource.createPixelMap(options).then(pixelMap => {this.image = pixelMap;})}}})
  • 常用函数
  • .objectFit(ImageFit.Fill)// 缩放类型
  • .interpolation(ImageInterpolation.High)//图片插值,抗锯齿,使图片看着更清晰
  • .renderMode(ImageRenderMode.Template) //图片渲染模式
  • .objectRepeat(ImageRepeat.X)//设置图片在xy轴上重复显示
  • .sourceSize({//设置图片解码尺寸
    width: 65, height: 40
    })
  • .colorFilter([//添加滤镜效果
    1,1,0,0,0,
    0,1,0,0,0,
    0,0,1,0,0,
    0,0,0,1,0
    ])
  • .syncLoad(true)//同步加载图片
  • .onComplete(msg=>{ 加载成功和失败的事件回调
    if (msg) {
    console.error(widthVal = ${msg.width}\n height = ${msg.height} \n componentW = ${msg.componentWidth} \n status = ${msg.loadingStatus})
    }
    })
    .onError(()=>{
    console.error(‘err’)
    })

2. 自定义图形(shape)

  • 有两种创建形式,一种以Shape为父组件,一种是绘制组件单独使用
Shape() {Rect().width(300).height(50)//以Shape作为父组件使用
}
Circle({ width: 150, height: 150 })//单独使用
  • 绘制组件有七种类型:圆形(Circle)、椭圆形(Ellipse)、直线(Line)、拆线(Polyline)、多边形(Polygon)、路径(Path)、矩形(Rect)。
  • 形状视口 viewPort
 Shape() {Rect({ width: 100, height: 100 }).fill(0xf7f7f7)Circle({ width: 150, height: 150 }).fill(0x00c250)}.viewPort({ x: 0, y: 0, width: 100, height: 100 })//根据这个视口与宽高比进行放大shape内的组件大小.width(150).height(150)
  • 绘制一个“吉”字
Path().width(100).height(100).commands(`M${this._50} 0 L${this._50} ${this._50} L0 ${this._50} L${this._100} ${this._50} L${this._50} ${this._50} L${this._50} ${this._100} L${this._15} ${this._100} L${this._85} ${this._100} L${this._50} ${this._100} Z`).fillOpacity(0) //实心不填充颜色.fill(Color.Red).stroke(Color.Red).strokeWidth(5)Polyline().width(100).height(100).stroke(Color.Red).strokeWidth(5).points([[10, 10], [90, 10], [90, 90], [10, 90], [10, 10]]).fillOpacity(0) //实心不填充颜色

3. 画布自定义图形(Canvas)

  • 初始化画布组件
  Canvas(this.context).width('100%').height('100%').backgroundColor(Color.Yellow).onReady(() => {
  • 画圆形
this.context.beginPath()
this.context.arc(110, 150, 50, 0, 6.28)
this.context.stroke()
this.context.font = '56px'
this.context.fillText('圆形', 120, 220)//画圆形
  • 画矩形
 this.context.beginPath()this.context.rect(110, 10, 210, 110)this.context.stroke()this.context.font = '46px'this.context.fillText('矩形', 120, 20)//画矩形
  • 画椭圆形
this.context.beginPath()this.context.ellipse(110, 250, 50, 100, Math.PI * 0.25, Math.PI * 0, Math.PI * 2)this.context.stroke()//画椭圆形
  • 写字
 let line = this.context.createLinearGradient(110, 500, 110, 600)line.addColorStop(0, '#f00')line.addColorStop(0.5, '#ff0')line.addColorStop(1, '#f0f')this.context.fillStyle = linethis.context.fillRect(110, 500, 100, 100)//渐变色this.context.fillText('我是中华人民共和国的公民', 110, 500)//写字
  • 截图画图
  this.offContext.drawImage(this.image, 110, 400, 130, 130)let imageData = this.offContext.getImageData(150, 450, 130, 130)this.offContext.putImageData(imageData, 130, 130)let img = this.offContext.transferToImageBitmap();this.context.transferFromImageBitmap(img)//.截图画图
  • 再次画个“吉”
let path = new Path2D();path.moveTo(100, 100)path.lineTo(100, 150)path.lineTo(25, 150)path.lineTo(175, 150)path.lineTo(100, 150)path.lineTo(100, 200)path.lineTo(40, 200)path.lineTo(160, 200)path.lineTo(100, 200)path.closePath()this.context.strokeStyle = '#f00'this.context.lineWidth = 5this.context.stroke(path)let path2 = new Path2D();path2.moveTo(40, 215)path2.lineTo(160, 215)path2.lineTo(160, 335)path2.lineTo(40, 335)path2.lineTo(40, 215)this.context.stroke(path2)//再次画个“吉”

二、 效果一览

在这里插入图片描述

三、 源码剖析

import http from '@ohos.net.http';
import ResponseCode from '@ohos.net.http';
import image from '@ohos.multimedia.image';
import picker from '@ohos.file.picker';@Entry
@Component
struct MyRouter {private tabsController: TabsController = new TabsController();@State currentIndex: number = 0;@Builder TabBuild(title: string, targetIndex: number, SelectedImg: Resource, normalImg: Resource) {Column() { //自定义tabImage(this.currentIndex == targetIndex ? SelectedImg : normalImg).size({ width: 25, height: 25 })Text(title).fontSize(16).fontColor(this.currentIndex == targetIndex ? 0x00c250 : 0x333333)}.width('100%').height(48).justifyContent(FlexAlign.Center).onClick(() => {console.error(`targetIndex is ${targetIndex}`)this.currentIndex = targetIndex;this.tabsController.changeIndex(this.currentIndex)})}@State image: PixelMap = undefined; //创建PixelMap状态变量private imgUrl: string = 'https://img1.baidu.com/it/u=3241660985,1063915045&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1194';loadImg() { //获取网络美女图片http.createHttp().request(this.imgUrl, (err, data) => {if (err) {console.error(`err is ${JSON.stringify(err)}`)} else {let code = data.responseCode;if (ResponseCode.ResponseCode.OK == code) {let res: any = data.result;let imageSource = image.createImageSource(res)let options = {alphaTye: 0, //透明度editable: false, //是否可编辑pixelFormat: 3, //像素格式scaleMode: 1, //缩略值size: { height: 100, wight: 100 } //创建图片大小}imageSource.createPixelMap(options).then(pixelMap => {this.image = pixelMap;})}}})}aboutToAppear() {// this.context = getContext();this.loadImg()}settings: RenderingContextSettings = new RenderingContextSettings(true)context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)img: ImageBitmap = new ImageBitmap('../../../resources/base/media/ic_hm_logo.svg')scroller: Scroller = new Scroller();@State _50: number = vp2px(50)@State _100: number = vp2px(100)@State _85: number = vp2px(85)@State _15: number = vp2px(15)@State _: number = vp2px(50)build() {Tabs({barPosition: BarPosition.End,controller: this.tabsController}) { //end start  首尾位置设置   controller 绑定tabs的控制器TabContent() { //内容页面组件MyNavigation().backgroundColor(0xf7f7f7)}.tabBar(this.TabBuild('首页', 0, $r('app.media.ic_hm_home_selected'), $r('app.media.ic_hm_home_normal')))TabContent() {Image(this.image).height('100%').width('100%')}.tabBar(this.TabBuild('直播', 1, $r('app.media.ic_hm_living_selected'), $r('app.media.ic_hm_living_normal')))TabContent() {Scroll(this.scroller) {Column() {Row() {Image(this.imgUrl).width('30%').height('20%').border({ width: 1 }).objectFit(ImageFit.Contain) //等比缩放,图片完全显示.margin(15).overlay('Contain', { align: Alignment.Bottom, offset: { x: 0, y: 30 } }).colorFilter([ //添加滤镜效果1, 1, 0, 0, 0,0, 1, 0, 0, 0,0, 0, 1, 0, 0,0, 0, 0, 1, 0]).syncLoad(true) //同步加载图片.onComplete(msg => {if (msg) {console.error(`widthVal = ${msg.width}\n height = ${msg.height} \n componentW = ${msg.componentWidth} \n status = ${msg.loadingStatus}`)}}).onError(() => {console.error('err')})Image(this.imgUrl).width('30%').height('20%').border({ width: 1 }).objectFit(ImageFit.Cover) //等比缩放, 图片显示部分.margin(15).overlay('Cover', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })Image(this.imgUrl).width('30%').height('20%').border({ width: 1 }).objectFit(ImageFit.Auto) //自适应显示.margin(15)}Row() {Image(this.imgUrl).width('30%').height('20%').border({ width: 1 }).objectFit(ImageFit.Fill) //填充显示,不保持等比缩放.renderMode(ImageRenderMode.Template) //图片渲染模式.margin(15).overlay('fill', { align: Alignment.Bottom, offset: { x: 0, y: 20 } })Image(this.imgUrl).sourceSize({ //设置图片解码尺寸width: 65, height: 40}).width('30%').height('20%').border({ width: 1 }).objectFit(ImageFit.ScaleDown) //保持原宽高比 等比缩放或不变.objectRepeat(ImageRepeat.XY) //设置图片在xy轴上重复显示.margin(15).overlay('scaleDown', { align: Alignment.Bottom, offset: { x: 0, y: 30 } })Image(this.imgUrl).width('30%').height('20%').border({ width: 1 }).objectFit(ImageFit.None) //保持图片原尺寸.interpolation(ImageInterpolation.High) //图片插值,抗锯齿,使图片看着更清晰.margin(15).overlay("none", { align: Alignment.Bottom, offset: { x: 0, y: 30 } })}}}.width('100%').height('100%')}.tabBar(this.TabBuild('朋友圈', 2, $r('app.media.ic_hm_friend_selected'), $r("app.media.ic_hm_friend_normal")))TabContent() {Canvas(this.context).width('100%').height('100%').backgroundColor(Color.Yellow).onReady(() => {this.offContext.drawImage(this.image, 110, 400, 130, 130)let imageData = this.offContext.getImageData(150, 450, 130, 130)this.offContext.putImageData(imageData, 130, 130)let img = this.offContext.transferToImageBitmap();this.context.transferFromImageBitmap(img)//.截图画图this.context.beginPath()this.context.rect(110, 10, 210, 110)this.context.stroke()this.context.font = '46px'this.context.fillText('矩形', 120, 20)//画矩形this.context.beginPath()this.context.arc(110, 150, 50, 0, 6.28)this.context.stroke()this.context.font = '56px'this.context.fillText('圆形', 120, 220)//画圆形this.context.beginPath()this.context.ellipse(110, 250, 50, 100, Math.PI * 0.25, Math.PI * 0, Math.PI * 2)this.context.stroke()//画椭圆形let line = this.context.createLinearGradient(110, 500, 110, 600)line.addColorStop(0, '#f00')line.addColorStop(0.5, '#ff0')line.addColorStop(1, '#f0f')this.context.fillStyle = linethis.context.fillRect(110, 500, 100, 100)//渐变色this.context.fillText('我是中华人民共和国的公民', 110, 500)//写字let path = new Path2D();path.moveTo(100, 100)path.lineTo(100, 150)path.lineTo(25, 150)path.lineTo(175, 150)path.lineTo(100, 150)path.lineTo(100, 200)path.lineTo(40, 200)path.lineTo(160, 200)path.lineTo(100, 200)path.closePath()this.context.strokeStyle = '#f00'this.context.lineWidth = 5this.context.stroke(path)let path2 = new Path2D();path2.moveTo(40, 215)path2.lineTo(160, 215)path2.lineTo(160, 335)path2.lineTo(40, 335)path2.lineTo(40, 215)this.context.stroke(path2)//再次画个“吉”})}.tabBar(this.TabBuild('画布', 3, $r('app.media.ic_hm_logo'), $r('app.media.icon')))TabContent() {Column() {Text('原始尺寸Circle')Circle({ width: 100, height: 100 }).fill(0x00c250)Row({ space: 10 }) {Column() {Text('shape内放大的Circle')Shape() {Rect({ width: 100, height: 100 }).fill(0xf7f7f7)Circle({ width: 150, height: 150 }).fill(0x00c250)}.viewPort({ x: 0, y: 0, width: 100, height: 100 }) //根据这个视口与宽高比进行放大shape内的组件大小.width(150).height(150)Path().width(100).height(100).commands(`M${this._50} 0 L${this._50} ${this._50} L0 ${this._50} L${this._100} ${this._50} L${this._50} ${this._50} L${this._50} ${this._100} L${this._15} ${this._100} L${this._85} ${this._100} L${this._50} ${this._100} Z`).fillOpacity(0) //实心不填充颜色.fill(Color.Red).stroke(Color.Red).strokeWidth(5)Polyline().width(100).height(100).stroke(Color.Red).strokeWidth(5).points([[10, 10], [90, 10], [90, 90], [10, 90], [10, 10]]).fillOpacity(0) //实心不填充颜色}}}}.tabBar(this.TabBuild('我的', 4, $r('app.media.ic_hm_my_selected'), $r('app.media.ic_hm_my_normal')))}.vertical(false) //tabs垂直与横向设置.scrollable(false) //禁止页面滑动.barMode((BarMode.Fixed)) //Fixed 固定    Scrollable  可以滑动,当tab多时用.onChange((index) => { //页面滑动监听console.error(`this is ${index}`)this.currentIndex = index;// this.tabsController.changeIndex(this.currentIndex)})}
}@Component
struct MyNavigation {private arr: number[] = [1, 2, 3];build() {Column() {Navigation() {TextInput({ placeholder: '请输入...' }).width('90%').height(40).backgroundColor('#ffffff')List({ space: 12 }) {ForEach(this.arr, item => {ListItem() {NavRouter() {Text("NavRouter" + item).width('100%').height(72).backgroundColor(Color.White).borderRadius(36).fontSize(16).fontWeight(500).textAlign(TextAlign.Center)NavDestination() {Text(`NavDestinationContent${item}`)}.title(`NavDestinationTitle${item}`)}}})}}.title('主标题').mode(NavigationMode.Stack).titleMode(NavigationTitleMode.Mini).menus([{ value: "", icon: './../../../resources/base/media/icon.png', action: () => {} },{ value: "", icon: './../../../resources/base/media/icon.png', action: () => {} }]).toolBar({ items: [{ value: 'func', icon: './../../../resources/base/media/icon.png', action: () => {} },{ value: 'func', icon: './../../../resources/base/media/icon.png', action: () => {} }] })}}
}

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

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

相关文章

AI 开发平台(Coze)搭建小游戏《挑战花光10亿》

前言 本文讲解如何从零开始,使用扣子平台去搭建一个小游戏 这是成品链接:挑战花光10亿 - 扣子 AI Bot (coze.cn) 欢迎大家去体验一下 效果 正文 什么是coze平台? 扣子(Coze)是字节跳动推出的一站式 AI 开发平台&am…

周末设计高端企业_集团官网主题Discuz模板

风格名称: 周末设计_高端企业_集团官网 适用版本: Discuz! X3.0、X3.1、X3.2、X3.3、F1.0 风格编码: 使用语言包结构,适合全部编码 周末设计高端企业_集团官网主题Discuz模板

会话会话会话

目录 1.会话 1.1 为什么需要会话控制 1.2 域对象的范围 1.2.1 应用域的范围 1.2.2 请求域的范围 1.2.3 会话域的范围 1.3 Cookie技术 1.3.1 Cookie的概念 1.3.2 Cookie的作用 1.3.3 Cookie的应用场景 1.3.4 Cookie的入门案例 ① 目标 ② Cookie相关的API ③ Serv…

C++ | Leetcode C++题解之第187题重复的DNA序列

题目&#xff1a; 题解&#xff1a; class Solution {const int L 10;unordered_map<char, int> bin {{A, 0}, {C, 1}, {G, 2}, {T, 3}}; public:vector<string> findRepeatedDnaSequences(string s) {vector<string> ans;int n s.length();if (n < L…

GPOPS-II教程(1): 语法和一个最优控制问题案例

文章目录 一、写在前面二、GPOPS-II结构2.1 setup的语法2.2 function的语法2.2.1 setup.functions.continuousfun2.2.2 setup.functions.endpoint 2.3 bounds的语法setup.guessoutput 三、例题3.1 问题描述3.2 代码部分3.2.1 main function3.2.1.1 初始参数设置3.2.1.2 边界条件…

安装VEX外部编辑器

Houdini20配置VEX外部编辑器方法_哔哩哔哩_bilibili 下载并安装Visual Studio Code软件&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 在Visual Studio Code软件内&#xff0c;安装相关插件&#xff0c;如&#xff1a; 中文汉化插件vex插件 安装Houdini Expr…

图像处理Python库--图片裁剪、缩放、灰度图、圆角等

图像处理Python库 py-img-processor1. 安装2. 使用(Usage)2.1 运行配置2.2 图像处理处理函数图像处理参数为字符串图像处理参数为JSON 命令行提取图像主色调 py-img-processor Image editor using Python and Pillow. 依赖Pillow开发的Python库&#xff0c;用于图像编辑处理。…

nest.js关键笔记

Nest.js 介绍核心功能设计模式&#xff1a;IOC 控制反转 DI 依赖注入前置知识&#xff1a;装饰器前置知识装饰器-实现一个GET请求 Nestjs脚手架Nestjs cli 常用命令 RESTful 风格设计Nestjs 控制器控制器中常见的参数装饰器 Session 实例Nestjs 提供者**工厂模式**异步模式 Nes…

【Unity服务器01】之【AssetBundle上传加载u3d模型】

首先打开一个项目导入一个简单的场景 导入怪物资源&#xff0c; AssetBundle知识点&#xff1a; 1.指定资源的AssetBundle属性标签 &#xff08;1&#xff09;找到AssetBundle属性标签 &#xff08;2&#xff09;A标签 代表&#xff1a;资源目录&#xff08;决定打包之后在哪…

如何给文档设置密码?电脑文件安全加密的详细操作步骤(10种方法)

在数字化时代&#xff0c;电脑文件的安全和隐私至关重要。通过给电脑的文件或者文件夹设置密码和加密&#xff0c;可以有效保护你的重要文件不被未经授权的人员访问&#xff0c;特别是公司的重要岗位&#xff0c;一些特殊的机密文件&#xff0c;投标文件&#xff0c;资金文件等…

动手学深度学习(Pytorch版)代码实践 -深度学习基础-10权重衰减

10权重衰减 """ 正则化是处理过拟合的常用方法&#xff1a;在训练集的损失函数中加入惩罚项&#xff0c;以降低学习到的模型的复杂度。 保持模型简单的一个特别的选择是使用L2惩罚的权重衰减。这会导致学习算法更新步骤中的权重衰减。 """impor…

html--好看的手机充值单页

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>线上充值-首页</title><meta content"widthdevice-width,initial-scale1.0,maximum-scale1.0,user-scalable0" name"viewport&…

maya模型仓鼠制作

小仓鼠建模&#xff08;6&#xff09;_哔哩哔哩_bilibili 20240623作品---个人评价&#xff1a;第一次做的&#xff0c;虽然有点丑&#xff0c;但是还能看&#xff01;希望后面有些进步

论文阅读--Efficient Hybrid Zoom using Camera Fusion on Mobile Phones

这是谷歌影像团队 2023 年发表在 Siggraph Asia 上的一篇文章&#xff0c;主要介绍的是利用多摄融合的思路进行变焦。 单反相机因为卓越的硬件性能&#xff0c;可以非常方便的实现光学变焦。不过目前的智能手机&#xff0c;受制于物理空间的限制&#xff0c;还不能做到像单反一…

线程封装,互斥

文章目录 线程封装线程互斥加锁、解锁认识接口解决问题理解锁 线程封装 C/C代码混编引起的问题 此处pthread_create函数要求传入参数为void * func(void * )类型,按理来说ThreadRoutine满足,但是 这是在内类完成封装,所以ThreadRoutine函数实际是两个参数,第一个参数Thread* …

【建设方案】大数据湖一体化建设方案(ppt原件)

1、背景&#xff1a;大数据湖的发展背景与建设理念 2、体系&#xff1a;大数据湖体系规划与建设思路 3、生态圈&#xff1a;探索新兴业务入湖建设模式 4、共享&#xff1a;大数据湖统一访问共享规划 5、运营&#xff1a;大数据湖一体化运营管理建设 &#xff08;本方案及更多方…

Kafka~基础原理与架构了解

Kafka是什么 Kafka我们了解一直认为是一个消息队列&#xff0c;但是其设计初&#xff0c;是一个&#xff1a;分布式流式处理平台。流平台具有三个关键功能&#xff1a; 消息队列&#xff1a;发布和订阅消息流&#xff0c;这个功能类似于消息队列&#xff0c;这也是 Kafka 也被…

Comfyui-ChatTTS-OpenVoice 为ComfyUI添加语音合成、语音克隆功能

‍‍ 生成多人播客&#xff1a; Comfyui-ChatTTS是一个开源的GitHub项目&#xff0c;致力于为ComfyUI添加语音合成功能。该项目提供了一系列功能强大的节点和模型&#xff0c;支持用户创建和复用音色&#xff0c;支持多人对话模式的生成&#xff0c;并提供了导出音频字幕文件的…

“Jedis与Redis整合指南:实现高效的Java应用与Redis交互“

目录 #. 概念 1. 导入jedis依赖 2. 写一个类&#xff08;ping通redis&#xff09; 3. String字符串使用 3.1 set&#xff0c;get方法使用&#xff08;设值&#xff0c;取值&#xff09; 3.2 mset&#xff0c;mget方法使用&#xff08;设置多个值&#xff0c;取多个值&…

怎么在vscode里运行一个cpp文件

文章目录 1.需要下载g编译器&#xff0c;或clang&#xff08;快&#xff0c;但是优化效果没有g好&#xff09;2.新建文件夹和cpp文件&#xff08;tasks.json&#xff09;3.怎么在vscode里调试(launch.json)4.怎么设置让中断输出的字符是中文&#xff01;5.飞机大战 1.需要下载g…