当前位置: 首页 > article >正文

【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.kler.cn/news/356015.html

相关文章:

  • Spring Boot框架的电影评论系统设计与实现
  • 多种方式实现安全帽佩戴检测
  • 上位机-简介
  • 与双指针的亲密接触:快与慢的浪漫交错
  • 细说网络安全五家龙头企业,你去过哪一家?
  • Linux 中,`tee` 和 `grep` 分别用于处理输出流[从标准输入读取数据,并将数据同时输出到标准输出和文件]和文本内容的过滤。
  • fmql之Linux Uart
  • 【C++刷题】力扣-#252-会议室
  • 【AI学习】Mamba学习(八):HiPPO通用框架定义和方法
  • JAVA学习-练习试用Java实现“选择排序”
  • 学生社会适应能力测试
  • 【最新华为OD机试E卷-支持在线评测】内存资源分配(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
  • WordPress+Nginx 安装教程
  • 越狱你的 iPhone 安全吗?
  • JMeter之mqtt-jmeter 插件介绍
  • 一个使用接口模式、工厂模式、模板方法模式的日志文件系统
  • Python画笔案例-086 turtle 多线程绘画
  • Unity Vision Pro 保姆级开发教程-PolySpatial VisionOS Samples 示例场景
  • 基于STM32设计的实验室安全预警系统(OneNet)(246)
  • ssm医院交互系统+vue