【Unity - 屏幕截图】技术要点

news/2024/10/16 16:08:56 标签: unity, 游戏引擎

在Unity中想要实现全屏截图或者截取某个对象区域的图片都是可以通过下面的函数进行截取

Texture2D

/// <summary>
    ///   <para>Reads the pixels from the current render target (the screen, or a RenderTexture), and writes them to the texture.</para>
    /// </summary>
    /// <param name="source">The region of the render target to read from.</param>
    /// <param name="destX">The horizontal pixel position in the texture to write the pixels to.</param>
    /// <param name="destY">The vertical pixel position in the texture to write the pixels to.</param>
    /// <param name="recalculateMipMaps">If this parameter is true, Unity automatically recalculates the mipmaps for the texture after writing the pixel data. Otherwise, Unity does not do this automatically.</param>
   public void ReadPixels(Rect source, int destX, int destY, [DefaultValue("true")] bool recalculateMipMaps)
   

Texture2D.ReadPixels() 函数参数可以翻译注释了解用法,比较简单,我下面简单说一下:

source: 读取像素的区域,坐标起点是 左下角,这个要注意

destX: 读取后写入到texture的坐标X

destY: 读取后写入到texture的坐标Y

recalculateMipMaps : 是否重新计算minimaps,逐级渐远纹理,一般都会关闭的,直接False

好,接下来,当你点击截图按钮,调用函数

    public void SaveImage(string path)
        {
            CoroutineManager.StartMonoCoroutine(SavePng(path));
        }

开启协程, 我用的是自己封装的管理器,你可以用原装的

然后开始截图操作,然后保存

     private IEnumerator SavePng(string path)
        {
        	//这里一定要等到帧渲染完毕
            yield return new WaitForEndOfFrame();
            
            //截图区域的本地坐标转换成 屏幕坐标
            var screenPoint = UiConfig.camera.WorldToScreenPoint(m_ScanImage.transform.position);
			
			//适配比例
            float ratio_x = Screen.width / 3662f; //注意这里,一定要加上比例
            //float ratio_y = Screen.height / 2060f;
            var imageWidth = m_ScanImage.rectTransform.sizeDelta.x * ratio_x;
            var imageHeight = m_ScanImage.rectTransform.sizeDelta.y * ratio_x;
            var t = new Texture2D((int)imageWidth, (int)imageHeight, TextureFormat.RGB24, false);
			
			//由于rect参数是从左下角开始读取,而我的m_ScanImage.transform锚点在左上角,所以rect的y值要减去他的高度
            t.ReadPixels(new Rect(screenPoint.x, screenPoint.y - imageHeight, imageWidth, imageHeight), 0, 0, false);
            t.Apply();

            var b = t.EncodeToPNG();
            if (b != null)
            {
                File.WriteAllBytes(path, b);
            }

这里说明一下 3662这个值的来历,看一下Canvas的设置
在这里插入图片描述
我的设计分辨率是4K的 3840 * 2060, 这里选择使用高度适配,宽度做拉伸,根据我电脑显示器的分辨率和Match = 1的比例换算后得出实际的设计分辨率 3662 * 2060 大致是这个

	//适配比例
            float ratio_x = Screen.width / 3662f; //注意这里,一定要加上比例
            var imageWidth = m_ScanImage.rectTransform.sizeDelta.x * ratio_x;
            var imageHeight = m_ScanImage.rectTransform.sizeDelta.y * ratio_x;

这个比例加上以后,你的缩放操作就不会影响截图的范围了

好了,大致的要点就这么多,下面说下 坐标转换 ,这个经常用到

// 本地坐标转屏幕坐标, 
 UiConfig.camera.WorldToScreenPoint(transform.position);  //注意这里使用position

//屏幕坐标转本地坐标
 var b = RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, screenPoint, cam, localPoint);

今天讲的都是比较基础的,温故而知新,祝大家生活工作愉快~!


http://www.niftyadmin.cn/n/5708191.html

相关文章

ES6新特性2- Promise的介绍和使用,map和set集合,ES6-新增对象方法, async和await

目录 一、Promise简介 二、Promise的三种状态 三、Promise的基本用法 四、Promise的实例方法 五、Promise的链式调用 六、Promise封装读取文件 步骤 七、promise封装AJAX请求 map和set() map() Set 拓展 注意 ES6-新增对象方法 1. Object.is() 2. Object.assign(…

【LeetCode】每日一题 2024_10_9 找到按位或最接近 K 的子数组(LogTrick、位运算)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;找到按位或最接近 K 的子数组 代码与解题思路 今天是 2100 的题目&#xff0c;难度略高&#xff0c;不在我的能力范围&#xff0c;推荐题解&#xff1a;两种方法&#xff1a;LogTrick/滑…

Prism导航入门学习笔记

首先创建一个空的Prism项目 在View文件夹中创建一个UserControl的A界面&#xff0c;再在ViewModel中创建一个AViewModel的类 在主页面中创建Button按钮&#xff0c;使用Command属性&#xff0c;指向导航命令的方法&#xff0c;CommandParameter指向导航的页面 <Grid><…

Go语言基础学习(Go安装配置、基础语法)

一、简介及安装教程 1、为什么学习Go&#xff1f; 简单好记的关键词和语法&#xff1b;更高的效率&#xff1b;生态强大&#xff1b;语法检查严格&#xff0c;安全性高&#xff1b;严格的依赖管理&#xff0c; go mod 命令&#xff1b;强大的编译检查、严格的编码规范和完整的…

C++学习路线(十六)

void类型指针 void -> 空类型 void* -> 空类型指针&#xff0c;只存储地址的值&#xff0c;丢失类型&#xff0c;无法访问&#xff0c;要访问里面的值 我们必须对指针进行正确的类型转换&#xff0c;然后再间接引用指针 所有其它类型的指针都可以隐式自动转换成 void 类型…

高级算法设计与分析 学习笔记13 线性规划

注意是线性规划不是动态规划哦 好家伙&#xff0c;这不是凸优化吗&#xff1f; 凸优化标准形式&#xff1a; 先改成统一最大化&#xff08;凸优化那边怎么是统一最小化&#xff1f;&#xff09; 原来的x2正负无所谓&#xff0c;但我希望每个x都是有限制的&#xff0c;所以把它改…

【整合包及教程】第二代GPT-SoVITS V2:革新声音克隆技术

随着人工智能技术的飞速发展&#xff0c;语音克隆技术也在不断进化。近期推出的第二代GPT-SoVITS V2&#xff0c;以其强大的功能和易用性&#xff0c;成为该领域的一大突破。GPT-SoVITS V2不仅能够基于少量的语音样本&#xff08;例如1分钟的音频&#xff09;来克隆音色&#x…

深入解析 Go 语言接口:多接口实现与接口组合的实际应用

文章目录 一、引言二、一个类型实现多个接口1. 定义多个接口2. 类型实现多个接口3. 使用多个接口 三、接口的组合1. 接口嵌套2. 实现复合接口 四、实际开发中的应用场景1. 多态与模块化设计2. 松耦合系统设计3. 测试与依赖注入4. 事件驱动架构中的应用 五、小结 一、引言 在 G…