【Godot4.2】图片处理函数库 - textureDB

概述

Godot中节点使用的图片是Texture2D或其子类型,而涉及图片处理,大多数功能在Image类型中,并且我们通常需要频繁的构造ImageImageTexture类型。
为了封装构造ImageImageTexture类型的代码,提供直接从文件到直接可以赋值给节点的纹理图片,或者从节点纹理直接获取处理后的纹理,所以笔者才起了创建这个静态函数库的想法。

代码

(会持续更新最新修改版本,另外请注意Godot版本)

# =============================================
# 名称:textureDB
# 类型:静态函数库
# 描述:一些简化处理ImageTexture的静态函数
# 作者:巽星石
# Godot版本:v4.2.1.stable.official [b09f793f5]
# 创建时间:20242822:48:38
# 最后修改时间:20242902:02:58
# =============================================
class_name textureDBenum ImageType{JPG,PNG,WEBP}   # 支持存储的图片类型# 直接从路径加载图片并返回ImageTexture
static func load_texture(img_path:String) -> ImageTexture:var texture = ImageTexture.new()var img = Image.load_from_file(img_path)texture = texture.create_from_image(img)return texture# 水平翻转Texture2D
static func flip_x_texture(texture:Texture2D) -> ImageTexture:var new_texture = ImageTexture.new()var img = texture.get_image()img.flip_x()new_texture = new_texture.create_from_image(img)return new_texture# 垂直翻转Texture2D
static func flip_y_texture(texture:Texture2D) -> ImageTexture:var new_texture = ImageTexture.new()var img = texture.get_image()img.flip_y()new_texture = new_texture.create_from_image(img)return new_texture# 创建并返回原图片的灰度图
static func gray_scale_texture(texture:Texture2D) -> ImageTexture:var new_texture = ImageTexture.new()var img = texture.get_image()for x in range(img.get_width()):for y in range(img.get_height()):var old_color = img.get_pixel(x,y)var gray = (old_color.r +  old_color.g +  old_color.b)/3var new_color = Color(gray,gray,gray,old_color.a)img.set_pixel(x,y,new_color)new_texture = new_texture.create_from_image(img)return new_texture# 获取并返回Texture2D的一个局部矩形区域
static func get_region(texture:Texture2D,region: Rect2i) -> ImageTexture:var new_texture = ImageTexture.new()var img = texture.get_image()img = img.get_region(region)new_texture = new_texture.create_from_image(img)return new_texture# 为图片添加边框
static func draw_border(texture:Texture2D,border_size:PackedInt32Array = [10,10,10,10],border_color:Color=Color.WHITE) -> ImageTexture:var new_texture = ImageTexture.new()# 1.通过原图和边框尺寸计算新图的尺寸var old_img = texture.get_image() # 原图片var new_img = Image.new()         # 新图片# 新的尺寸 = 原图片尺寸 + 边框尺寸var new_size = old_img.get_size() + Vector2i(border_size[1] + border_size[3],border_size[0] + border_size[2])# 2.通过新尺寸构造新的Imagenew_img = new_img.create(new_size.x,new_size.y,false,Image.FORMAT_RGBA8)new_img.fill(border_color)  # 填充整个纹理区域为边框颜色# 3.在新图的指定位置绘制原图var rect = old_img.get_used_rect()                # 原图的纹理区域var pos = Vector2i(border_size[3],border_size[0]) # 起始位置new_img.blit_rect(old_img,rect,pos)               # 将原图绘制到新Image的指定区域# 4.通过新Image构造ImageTexturenew_texture = new_texture.create_from_image(new_img)return new_texture# 创建纯色块的ImageTexture
static func color_block(size:Vector2,color:Color=Color.WHITE) -> ImageTexture:var new_texture = ImageTexture.new()var img = Image.new()img = img.create(size.x,size.y,false,Image.FORMAT_RGBA8)img.fill(color)new_texture = new_texture.create_from_image(img)return new_texture# 创建棋盘格的ImageTexture
static func checker_board(img_size:Vector2i,cell_size:Vector2i=Vector2i(10,10),color1:Color=Color.WHITE,color2:Color=Color.BLACK) -> ImageTexture:var new_texture = ImageTexture.new()var img = Image.new()img = img.create(img_size.x,img_size.y,false,Image.FORMAT_RGBA8)# 计算所需要填充的数量var grid_size = ceil(img_size / cell_size) for x in range(grid_size.x):for y in range(grid_size.y):var rect = Rect2i(cell_size * Vector2i(x,y),cell_size)if (x % 2 == 0 and y % 2 == 0) or (x % 2 == 1 and y % 2 == 1): # 奇数行奇数列,或者偶数行偶数列img.fill_rect(rect,color1)else:img.fill_rect(rect,color2)new_texture = new_texture.create_from_image(img)return new_texture# 直接将Texture2D保存为本地图片文件
static func save_texture(texture:Texture2D,file_path:String,img_type:ImageType=ImageType.JPG) -> void:var img = texture.get_image()match img_type:ImageType.JPG:img.save_jpg(file_path)ImageType.PNG:img.save_png(file_path)ImageType.WEBP:img.save_webp(file_path)# 生成Image的缩略图
static func create_thumb(img:Image,size:Vector2) -> ImageTexture:var texture = ImageTexture.new()var old_size = img.get_size()  # 原图尺寸var aspect_ratio = old_size.aspect()# 原图比缩略图宽或高时if old_size.x > size.x or old_size.y > size.y:if old_size.x > old_size.y: # 图片水平方向比较长var new_w = size.xvar new_h = size.x / aspect_ratioimg.resize(new_w,new_h)else:var new_h = size.y var new_w = size.y * aspect_ratioimg.resize(new_w,new_h,Image.INTERPOLATE_LANCZOS)texture = texture.create_from_image(img)return texture# 生成指定路径文件的缩略图
static func create_thumb_from_file(img_path:String,size:Vector2) -> ImageTexture:var texture = ImageTexture.new()if img_path.get_extension() in ["png","jpg","svg"]:var img = Image.load_from_file(img_path)if img:texture = create_thumb(img,size)return textureelse:return null

用法示例

我们创建一个测试场景,添加一个TextureRect控件。

在这里插入图片描述

并设定如下:

在这里插入图片描述

加载图片文件到节点

为根节点创建如下代码:

extends Control@onready var texture_rect = $TextureRectfunc _ready():# 从文件加载图片texture_rect.texture = textureDB.load_texture("res://icon.svg")

运行后就可以看到图片被正确加载,这种直接加载图片文件为纹理的形式,比构造ImageTextureImage要简化的多了。

在这里插入图片描述

水平翻转图片

为了更好的展示图片处理效果,我们使用一张更大更复杂的图片。下面是原图加载后的效果:

在这里插入图片描述

修改设置如下:

在这里插入图片描述

根节点代码修改如下:

extends Control@onready var texture_rect = $TextureRectfunc _ready():var img_path = "C:/Users/Lenovo/Pictures/Screenshots/屏幕截图 2024-02-06 150512.png"# 从文件加载图片var texture = textureDB.load_texture(img_path)# 赋值水平翻转后的图片texture_rect.texture = textureDB.flip_x_texture(texture)

运行后的效果:

在这里插入图片描述
可以看到图片被水平翻转,而且没有涉及Image的底层操作。

垂直翻转图片

垂直翻转的代码很类似,只需要将flip_x_texture改为flip_y_texture就可以了。

extends Control@onready var texture_rect = $TextureRectfunc _ready():var img_path = "C:/Users/Lenovo/Pictures/Screenshots/屏幕截图 2024-02-06 150512.png"# 从文件加载图片var texture = textureDB.load_texture(img_path)# 赋值水平翻转后的图片texture_rect.texture = textureDB.flip_y_texture(texture)

垂直翻转效果:

在这里插入图片描述

局部裁切(显示图片局部)

通过get_region可以获取相应纹理的的一个局部。

extends Control@onready var texture_rect = $TextureRectfunc _ready():var img_path = "C:/Users/Lenovo/Pictures/Screenshots/屏幕截图 2024-02-06 150512.png"# 从文件加载图片var texture = textureDB.load_texture(img_path)# 赋值局部裁切图片texture_rect.texture = textureDB.get_region(texture,Rect2i(100,100,500,500))

效果如下:

在这里插入图片描述

可以应用于用户头像、封面图片裁切等场景。

绘制边框

在图片处理中有时候需要描边或绘制边框,draw_border可以为原图外部添加四个边上的描边,而且可以设定每个边不一样的宽度。

extends Control@onready var texture_rect = $TextureRectfunc _ready():var img_path = "C:/Users/Lenovo/Pictures/Screenshots/屏幕截图 2024-02-06 150512.png"# 从文件加载图片var texture = textureDB.load_texture(img_path)# 赋值添加描边效果的图片texture_rect.texture = textureDB.draw_border(texture)

默认的10像素边框:

在这里插入图片描述
可以自定义各个边的尺寸,顺序为:上右底左。

extends Control@onready var texture_rect = $TextureRectfunc _ready():var img_path = "C:/Users/Lenovo/Pictures/Screenshots/屏幕截图 2024-02-06 150512.png"# 从文件加载图片var texture = textureDB.load_texture(img_path)# 赋值添加描边效果的图片texture_rect.texture = textureDB.draw_border(texture,[200,100,200,100])

自定义边框宽度效果:

在这里插入图片描述

另外,边框颜色也可以自定义:

extends Control@onready var texture_rect = $TextureRectfunc _ready():var img_path = "C:/Users/Lenovo/Pictures/Screenshots/屏幕截图 2024-02-06 150512.png"# 从文件加载图片var texture = textureDB.load_texture(img_path)# 赋值添加描边效果的图片texture_rect.texture = textureDB.draw_border(texture,[200,100,200,100],Color.YELLOW_GREEN)

在这里插入图片描述

纯色块

color_block指定一个大小和颜色,就可以直接创建一个纯色块图片。默认为白色。

extends Control@onready var texture_rect = $TextureRectfunc _ready():# 赋值纯色块texture_rect.texture = textureDB.color_block(Vector2(200,200))

在这里插入图片描述

棋盘格

checker_board用于参数化的创建棋盘格纹理,可以看做是我的第一个纹理图片生成函数,当然基于CanvasItem的绘制函数,已经创建过棋盘格了。

extends Control@onready var texture_rect = $TextureRectfunc _ready():# 赋值棋盘格texture_rect.texture = textureDB.checker_board(Vector2i(100,100),Vector2i(10,10))

在这里插入图片描述
通过设定两个颜色,可以绘制彩色棋盘格。

extends Control@onready var texture_rect = $TextureRectfunc _ready():# 赋值棋盘格texture_rect.texture = textureDB.checker_board(Vector2i(100,100),Vector2i(10,10),Color.AQUA,Color.AQUAMARINE)

在这里插入图片描述

创建灰度图

基于每个像素点RGB值相加除以3的做法,相对效率不是太高。但算勉强实现,使用多线程可能会加速一些。不过确实可以实现图片处理并输出为本地文件,一般使用还是用Shader实现吧,效率高多了。

extends Control@onready var texture_rect = $TextureRectfunc _ready():var img_path = "C:/Users/Lenovo/Pictures/Screenshots/屏幕截图 2024-02-06 150512.png"# 从文件加载图片var texture = textureDB.load_texture(img_path)# 赋值灰度图texture_rect.texture = textureDB.gray_scale_texture(texture)

在这里插入图片描述

创建缩略图

(等待施工…2024年2月9日01:37:37)

保存纹理为本地文件

(等待施工…2024年2月9日01:37:37)

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

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

相关文章

【开源】SpringBoot框架开发校园电商物流云平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 商品数据模块2.3 快递公司模块2.4 物流订单模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 商品表3.2.2 快递公司表3.2.3 物流订单表 四、系统展示五、核心代码5.1 查询商品5.2 查询快递公司5.3 查…

CentOS 安装 redis 7.2

nginx官网 https://redis.io/download/ 把鼠标放到这里,复制下载地址 在服务器找个文件夹执行命令 wget https://github.com/redis/redis/archive/7.2.4.tar.gz tar -zxvf 7.2.4.tar.gz make make install 看到这几行就说明安装成功了 不放心的话再查看下b…

26、Makefile/shell/字符串处理相关练习20240208

一、现有文件test.c\test1.c\main.c , 请编写Makefile. vi Makefile 创建 代码: CCgcc EXEwho OBJS$(patsubst %.c,%.o,$(wildcard *.c)) FLAGS-c -oall:$(EXE)$(EXE):$(OBJS)$(CC) $^ -o $%.o:%.c$(CC) $(FLAGS) $ $^.PHONY:cleanclean:rm $(OBJS) $(EXE)运行&a…

Javaweb之SpringBootWeb案例之异常处理功能的详细解析

3. 异常处理 3.1 当前问题 登录功能和登录校验功能我们都实现了,下面我们学习下今天最后一块技术点:异常处理。首先我们先来看一下系统出现异常之后会发生什么现象,再来介绍异常处理的方案。 我们打开浏览器,访问系统中的新增部…

Flask基础学习

1.debug、host、port 模式修改 1) debug模式 默认debug模式是off,在修改代码调试过程中需要暂停重启使用,这时可修改on模式解决。 同时在debug模式开启下可看到出错信息。 下面有关于Pycharm社区版和专业版修改debug模式的区别 专业版 社区版&#…

springboo冬奥会科普平台源码和论文

随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理平台应运而生,各行各业相继进入信息管理时代&#xf…

人大金仓bat文件备份数据库

1)使用环境变量来存储密码 setx KINGBASE_PASSWORD "abc123" 2)编写backup.bat :: 设置备份参数 set "sys_dumpc:\Program Files\Kingbase\ES\V8\KESRealPro\V008R006C008B0014\ClientTools\bin\sys_dump" set "hostloca…

Spring Boot 笔记 003 Bean注册

使用Idea导入第三方jar包 在porn.xml种添加的第三方jar包依赖,并刷新 可以在启动类中尝试调用 以上放到启动类中,不推荐,建议创建一个专门定义的类 package com.geji.config;import cn.itcast.pojo.Country; import cn.itcast.pojo.Province;…

[CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理

文章目录 前言一、所需环境二、实现思路2.1. 定义了LeNet网络模型结构,并训练了20次2.2 以txt格式导出训练结果(模型的各个层权重偏置等参数)2.3 (可选)以pth格式导出训练结果,以方便后期调试2.4 C CUDA要做的事 三、C CUDA具体实现3.1 新建.cu文件并填好…

C语言:分支与循环

创造不易,友友们给个三连吧!! C语⾔是结构化的程序设计语⾔,这⾥的结构指的是顺序结构、选择结构、循环结构,C语⾔是能够实 现这三种结构的,其实我们如果仔细分析,我们⽇常所⻅的事情都可以拆分…

【Linux】文件的软硬链接

文章目录 一、文件和目录的一些命令ls 命令stat 命令 二、链接的概念三、软链接(symbolic link)创建和删除软链接的示例软链接的特性软链接的应用使用 find 查找链接文件 四、硬链接(hard link)创建和删除硬链接的示例硬链接的特性…

js手写Promise(上)

目录 构造函数resolve与reject状态改变状态改变后就无法再次改变 代码优化回调函数中抛出错误 thenonFulfilled和onRejected的调用时机异步then多个then 如果是不知道或者对Promise不熟悉的铁铁可以先看我这篇文章 Promise 构造函数 在最开始,我们先不去考虑Promi…

代码随想录算法训练营DAY16 | 二叉树 (3)

一、LeetCode 104 二叉树的最大深度 题目链接:104.二叉树的最大深度https://leetcode.cn/problems/maximum-depth-of-binary-tree/ 思路:采用后序遍历递归求解。 class Solution {int ans 0;public int maxDepth(TreeNode root) {if(root null){retur…

wyh的迷宫

涉及知识点:求迷宫能否到达终点的,而不是求路径数的,用bfs时可以不用重置状态数组(回溯)。 题目描述 给你一个n*m的迷宫,这个迷宫中有以下几个标识: s代表起点 t代表终点 x代表障碍物 .代…

PHPExcel导出excel

PHPExcel下载地址 https://gitee.com/mirrors/phpexcelhttps://github.com/PHPOffice/PHPExcel 下载后目录结构 需要的文件如下图所示 将上面的PHPExcel文件夹和PHPExcel.php复制到你需要的地方 这是一个简单的示例代码 <?php$dir dirname(__FILE__); //require_once …

Unity3d Shader篇(五)— Phong片元高光反射着色器

文章目录 前言一、Phong片元高光反射着色器是什么&#xff1f;1. Phong片元高光反射着色器的工作原理2. Phong片元高光反射着色器的优缺点优点缺点 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四、总…

SpringBoot WebSocket客户端与服务端一对一收发信息

依赖 <!--websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>配置类 Configuration public class WebSocketConfig {Bean //方法返回值交…

微软.NET6开发的C#特性——委托和事件

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;看到不少初学者在学习编程语言的过程中如此的痛苦&#xff0c;我决定做点什么&#xff0c;下面我就重点讲讲微软.NET6开发人员需要知道的C#特性&#xff0c;然后比较其他各种语言进行认识。 C#经历了多年发展…

【Spring源码解读!底层原理进阶】【上】探寻Spring内部:BeanFactory和ApplicationContext实现原理揭秘✨

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;底层原理高级进阶》 &#x1f680…

Docker部署前端项目

某次阿里云的自动流水线失败了&#xff0c;代码本地跑起来莫得问题&#xff0c;错误日志提示让我跑一下npm run build &#xff0c;但是俺忽然发现&#xff0c;我跑了&#xff0c;文件打包好了&#xff0c;但是往哪里运行呢&#xff1f;这涉及到要构建一个环境供打包文件部署吧…