Unity开发笔记:截取指定位置含有UI的场景截图并输出

news2024/9/23 9:24:11

学习记录整理,自用,也希望能帮助到有相同需求的人。
如果直接截全图:

        string screenshotName = "Assets/Textures/UI/20230803/2.png";
        ScreenCapture.CaptureScreenshot(screenshotName);

截取指定位置含有UI的场景截图:
例如这种情况下只想要中间的:
在这里插入图片描述

UI所在的Canvas设置为RenderMode.ScreenSpaceCamera并挂载相机,然后设置该相机的渲染RenderTexture并开始render,注意这里渲染是从屏幕中心扩展到四周,也就是说RenderTexture小于屏幕的话只能看到中间部分,然后代码如下,已添加注释。
函数中0、1、2三张图只是为了表明ReadPixels中坐标具体参数细节,可删去。
为了方便,我直接使用我的图片的固定大小500*500,自用可以自行获取所需图片尺寸。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TextureExporter : MonoBehaviour
{
    public Texture2D textureToExport;
    public string exportPath = "Assets/ExportedImages/";
    public RectTransform uiRectTransform; 
    public Camera mainCamera;
    private void Start()
    {
        ExportUIAsImage(exportPath);
        string screenshotName = "Assets/ExportedImages/5.png";
        ScreenCapture.CaptureScreenshot(screenshotName);
    }
    public void ExportUIAsImage(string path)
    {
        GameObject cameraObj = new GameObject("MyCamera");
        Camera cameraComponent = cameraObj.AddComponent<Camera>();

        // 获取UI元素所在的Canvas组件
        Canvas canvas = uiRectTransform.GetComponentInParent<Canvas>();
        canvas.renderMode = RenderMode.ScreenSpaceCamera;
        canvas.worldCamera = cameraComponent;

        // 获取 UI 的宽度和高度
        float width = 1080;
        float height = 1920;

        // 创建 RenderTexture 来保存 UI 的截屏
        RenderTexture renderTexture = new RenderTexture( 1080,1920, 24);
        Camera mainCamera = cameraComponent;

        // 将 UI 渲染到 RenderTexture 中
        mainCamera.targetTexture = renderTexture;
        mainCamera.Render();

        // 保存当前 RenderTexture 作为激活的 RenderTexture
        RenderTexture currentRT = RenderTexture.active;
        RenderTexture.active = renderTexture;

        // 创建一个新的 Texture2D 来保存截屏数据
        Texture2D uiTexture = new Texture2D((int)width, (int)height, TextureFormat.RGB24, false);
        Texture2D uiTexture1 = new Texture2D(500, 500, TextureFormat.RGB24, false);
        Vector3 localTopLeft = new Vector3(uiRectTransform.rect.xMin, uiRectTransform.rect.yMax, 0f);

        // 将本地坐标转换为屏幕坐标
        Vector3 screenTopLeft = uiRectTransform.TransformPoint(localTopLeft);
        Vector3 screenPoint = cameraComponent.WorldToScreenPoint(screenTopLeft);

        uiTexture1.ReadPixels(new Rect(screenPoint.x, 1920- screenPoint.y, 500, 500), 0, 0);
        uiTexture1.Apply();
        // 将 Texture2D 保存为图片文件
        byte[] imageBytes1 = uiTexture1.EncodeToPNG(); 
        System.IO.File.WriteAllBytes(exportPath + "/4.png", imageBytes1);

        //ReadPixels截取Rect部分内容是以左上角为原点,右方为x轴正向下方为y轴正向
        //ReadPixels输出到uiTexture部分内容是以左下角为原点,右方为x轴正向上方为y轴正向
        uiTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);

        uiTexture.Apply();
        // 将 Texture2D 保存为图片文件
        byte[]imageBytes = uiTexture.EncodeToPNG(); // 或者使用 EncodeToJPG
        System.IO.File.WriteAllBytes(exportPath + "/0.png", imageBytes);


        uiTexture.ReadPixels(new Rect(0, 0, width-500, height - 500), 0, 0);
        uiTexture.Apply();
        // 将 Texture2D 保存为图片文件
         imageBytes = uiTexture.EncodeToPNG(); 
        System.IO.File.WriteAllBytes(exportPath + "/1.png", imageBytes);

        uiTexture.ReadPixels(new Rect(500, 0, width - 500, height - 500), 0, 0);
        uiTexture.Apply();
        // 将 Texture2D 保存为图片文件
        imageBytes = uiTexture.EncodeToPNG(); // 或者使用 EncodeToJPG
        System.IO.File.WriteAllBytes(exportPath + "/2.png", imageBytes);


        // 清理资源
        mainCamera.targetTexture = null;
        RenderTexture.active = currentRT;
        Destroy(uiTexture);
        Destroy(renderTexture);

        Debug.Log("UI 已导出为图片至:" + exportPath + "/screenshot.png");
    }
};

输出情况:

在这里插入图片描述
0和5直接签全图效果一样。
0:
在这里插入图片描述

1:
在这里插入图片描述

2:
在这里插入图片描述

4:
在这里插入图片描述

5:
在这里插入图片描述

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

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

相关文章

Therac-25事故:软件缺陷引发的医疗灾难与教训

目录 引言 Therac-25&#xff1a;背景与功能 软件缺陷导致的灾难 Bug原理解析与编程人员的反思 教训与反思 结论 引言 在计算机科技的进步与应用领域&#xff0c;软件的质量和安全性至关重要。然而&#xff0c;历史上曾经发生过一系列令人震惊的事件&#xff0c;突显了软…

培训报名小程序报名功能完善

目录 1 修改数据源2 修改表单3 支付成功时修改状态4 创建报名成功页5 最终的效果总结 目前我们的报名功能已经搭建了一个基础版&#xff0c;后续需要展示用户已经报名的信息&#xff0c;需要添加一个状态来显示用户是否成功付费。 1 修改数据源 打开我们的报名数据源&#xff…

google PGS 下一代id

前言&#xff1a;为了进一步增强用户的隐私及其多平台游戏体验&#xff0c;Play 游戏服务(PGS) 正在推出下一代玩家 ID&#xff0c;用户第一次玩游戏时&#xff0c;他们将始终被分配一个唯一的下一代玩家 ID&#xff0c;无论用户在什么设备或平台上玩游戏&#xff0c;该 ID 都将…

加入[无人驾驶吕同学]Apollo专属课程领礼品啦!

号外号外&#xff0c;无人驾驶吕同学的Apollo领航官专属课程已经上线了。用户完成课程50%即可领取专属福利&#xff08;百度限定鼠标垫、Apollo限量帆布包、Apollo六周年定制钥匙扣、Apollo六周年限定徽章&#xff09;&#xff0c;四种礼品任选其一。 课程链接&#xff1a;htt…

使用 Docker 和 Streamlit 构建和部署 LangChain 支持的聊天应用程序

文章目录 前言聊天应用程序组件和技术LangChain Python框架开放人工智能模型前端 Streamlit UI使用 Docker 进行部署Docker 优化以实现轻量级和快速构建Docker-compose.yaml 文件基础设施Streamlit 公共云谷歌应用引擎使用 Google Cloud Run 部署应用1.启动服务2. 创建角色并将…

水产养殖产量低?教你个万能的方法!

水产养殖业作为重要的食品生产和经济活动之一&#xff0c;为人们提供了丰富的水产品&#xff0c;但如果不加以适当监测和管理&#xff0c;也可能对水质和生态系统造成负面影响。因此&#xff0c;水产养殖用水监测显得尤为重要。 在养殖过程中&#xff0c;水质的优劣直接影响着养…

Linux小型操作系统项目,《操作系统真象还原》第三章——完善MBR

前引 上一章我们完成了MBR的雏形编写&#xff0c;但是只打印了几个字符&#xff0c;这一章我们才要真正地去完成MBR的功能。 在完成MBR的功能之前我们要先了解一些知识&#xff0c;首先介绍什么是实模式。 书上的内容实在繁杂&#xff0c;简单地说&#xff0c;实模式没有虚拟和…

【算法|数组】双指针

算法|数组——双指针 引入 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;…

77. 组合

题目链接&#xff1a;力扣 解题思路&#xff1a; AC代码 class Solution {List<Integer> tem new ArrayList<>();List<List<Integer>> result new ArrayList<>();public List<List<Integer>> combine(int n, int k) {process(n…

重试框架入门:Spring-RetryGuava-Retry

前言 在日常工作中&#xff0c;随着业务日渐庞大&#xff0c;不可避免的涉及到调用远程服务&#xff0c;但是远程服务的健壮性和网络稳定性都是不可控因素&#xff0c;因此&#xff0c;我们需要考虑合适的重试机制去处理这些问题&#xff0c;最基础的方式就是手动重试&#xf…

Vue3:页面A搜索后跳转到页面B,然后从页面B退回页面A重新搜索,但是得到的页面B得刷新一下才会显示正确的数据

问题 Vue3&#xff1a; 从页面A进行搜索后跳转到页面B&#xff0c;然后从页面B退回页面A重新搜索&#xff0c;但是得到的页面B得刷新一下才会显示正确的数据。 读取数据的代码格式大致如下&#xff08;代码做了一些删减&#xff09;&#xff1a; 解决 会出现上述情况&#…

DIY 一个 Docker Base Image

1. 我们先使用C语言写一个hello-world程序 vim hello.c # include <stdio.h>int main() {print("hello docker\n"); } 2. 将hello.c文件编译成二进制文件, 需要安装工具 yum install gcc yum install glibc-static 开始编译 gcc -static hello.c -o hello 编译…

低代码平台“高”效率开发的5个能力

迫于智改数转的压力&#xff0c;促使企业要不停地思考如何从低代码的角度释放一些重复枯燥又高成本的人力投入。历经多次重大重构及大量项目实战验证之后&#xff0c;个人认为一款高效率的低代码开发平台&#xff0c;应有以下几点能力。 一、低代码平台“高”效率开发的5个能力…

ES索引重建reindex详解

目录 一、使用场景 二、reindex介绍 三、使用手册 1、覆盖更新 2、创建丢失的文档并更新旧版本的文档 3、仅创建丢失的文档 4、冲突处理 5、source中添加查询条件 6、source中包含多个源索引 7、限制处理的记录数 8、从远程ES集群中重建索引 9、提取随机子集 10、…

Java实现轻量型Web服务器接收http协议提交的RFID读卡信息

示例使用的读卡器&#xff1a;RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSock…

Java-day07(面向对象-3,4)

继承 将多个类中共有的属性&#xff0c;方法剥离出来单独创建一个共有类&#xff0c;当需要使用共有的属性与方法时&#xff0c;就可以通过继承(extends)来调用共有的属性与方法。通过"class A extends B" 来实现类的继承&#xff08;子类&#xff1a;A 父类&#x…

手把手教你 使用SpringBoot 实现业务数据动态脱敏

文章目录 什么是数据脱敏静态数据脱敏动态数据脱敏 需求实现1. 切面AOP实现脱敏是否脱敏注解定义切入点测试单条记录结果多条记录结果分页记录结果 2. 自定义注解和自定义消息转换器实现数据脱敏自定义DataDesensitization注解定义脱敏类型枚举实现AnnotationFormatterFactory接…

SAP度量单位转换功能

针对今天N2项目提出业务痛点&#xff1a;物料30011110的基本单位是KG&#xff0c;在XXX的BOM里单位是G&#xff0c;由于物料没配单位转换关系&#xff0c;但系统又能正常进行转换&#xff0c;开发需要技术支持。 经专项调查&#xff0c;G和KG的转换是SAP相同量纲转换标准功能&…

econml双机器学习实现连续干预和预测

连续干预 在这个示例中&#xff0c;我们使用LinearDML模型&#xff0c;使用随机森林回归模型来估计因果效应。我们首先模拟数据&#xff0c;然后模型&#xff0c;并使用方法来effect创建不同干预值下的效应&#xff08;Conditional Average Treatment Effect&#xff0c;CATE&…

现在转行搞嵌入式找工作难不难啊?

对于应届生来说&#xff0c;嵌入式开发的经验不会有太多&#xff0c;所以要求也不会太高。 嵌入式开发常用的是C语言&#xff0c;所以需要你有扎实的功底&#xff0c;这一点很重要&#xff0c;数据结构算法&#xff0c;指针&#xff0c;函数&#xff0c;网络编程 有了上面的基…