unity(WebGL) 截图拼接并保存本地,下载PDF

news2024/11/26 19:23:43

截图参考:Unity3D 局部截图、全屏截图、带UI截图三种方法_unity 截图_野区捕龙为宠的博客-CSDN博客

文档下载: Unity WebGL 生成doc保存到本地电脑_unity webgl 保存文件_野区捕龙为宠的博客-CSDN博客

中文输入:Unity WebGL中文输入 支持输入法跟随 支持全屏(内附Dome)_unity中文插件-CSDN博客 

1.调用代码

 private void Awake()
    {
//点击提交下载 按钮
        Btn_download.onClick.AddListener(() =>
        {
            Btn_download.gameObject.SetActive(value: false);

            GetComponent<Capture_Long>().Cap_LongTex();//截图拼图
//下载PDF
            GetComponent<Capture_Long>().CapCallBack = ((png_byte) =>
            {
                string filename = CQOOC.Instance.userName + "_" + DateTime.Now.ToString("g");
                Btn_download.gameObject.SetActive(true);
                Application.ExternalCall("downloadPng", png_byte, filename);//调用 webgl 方法

              //  Debug.Log("filename="+ filename);
            });
//上传 截图
            GetComponent<Capture_Long>().CapByteCallBack = ((png_byte) =>
            {
                string filename = CQOOC.Instance.userName + "_" + DateTime.Now.ToString("g");
                Debug.Log("filename=" + filename);
                //上传实验报告 截图
                CQOOC.Instance.UploadFile(png_byte, filename+".png", ((b) => {
                    if (b)
                    {
                        Debug.Log("上传截图成功!");
                    }
                    else
                    {
                        Debug.Log("上传截图失败!");
                    }
                }));

                //上传实验报告 数据
                CQOOC.Instance.UploadData_((b) => {
                    if (b)
                    {
                        UITipDialogMini.Instance.SetState(true, "提交数据成功!");
                    }
                    else
                    {
                        UITipDialogMini.Instance.SetState(true, "提交数据失败!");
                    }
                });

            });
        });
        DateTime now = DateTime.Now.AddMinutes(-15);
        string formattedTime = now.ToString("yyyy 年 M 月 d 日 HH:mm:ss");
        text_StartTime.text = formattedTime;

        DateTime now02 = DateTime.Now;
        string formattedTime02 = now02.ToString("yyyy 年 M 月 d 日 HH:mm:ss");
        text_EndTime.text = formattedTime02;

        // text_StartTime.text = DateTime.Now.AddMinutes(-15).ToString("F");
        //text_EndTime.text = DateTime.Now.ToString("F");

        text_UserName.text = CQOOC.Instance.userName;
        text_Score.text = UnityEngine.Random.Range(80f, 95f).ToString("0");
    }

  

 

2.截图 拼图 代码

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

public class Capture_Long : MonoBehaviour
{
    public RectTransform svrt;
    public RectTransform contentRT;
    public Action<string> CapCallBack;
    public Action<byte[]> CapByteCallBack;
    public Vector2 vec;

    /// <summary>
    /// 接长图,进行拼接
    /// </summary>
    /// <param name="SVRT">Scroll Rect</param>
    /// <param name="ContentRT">Content</param>
    public void Cap_LongTex()
    {
        StartCoroutine(Cap(svrt, contentRT));
    }
    private IEnumerator Cap(RectTransform SVRT, RectTransform ContentRT)
    {
        //画布中的高度      950
        float SV_Y = SVRT.sizeDelta.y;

        //content显示的区域高度   0
        float Content_Y = ContentRT.anchoredPosition.y;
        //图片的整体高度   2660
        float Content_Height = contentRT.sizeDelta.y+ SV_Y;

        var mult = (float)(Content_Height / SV_Y);
        //整数倍
        int mult_int = (int)mult;
        //最后的小数倍
        float mult_float = mult - mult_int;

        //滚动条的宽度
        float verticalScrollbar_weight = SVRT.GetComponent<ScrollRect>().verticalScrollbar.GetComponent<RectTransform>().sizeDelta.x;

        yield return new WaitForEndOfFrame();

        //合成图片的总高度
        int totalHeight = (int)Content_Height;
        Texture2D endTex = new Texture2D((int)vec.y, totalHeight, TextureFormat.RGBA32, false);
        int x = 0, y = 0;
        Color32[] colors;

        //整数倍的截图
        for (int i = 0; i < mult_int; i++)
        {
            ContentRT.anchoredPosition = new Vector2(0, SV_Y * i);
            yield return new WaitForEndOfFrame();
            //Rect rect_int = new Rect(Screen.width / 2 - SVRT.sizeDelta.x / 2 + SVRT.anchoredPosition.x, Screen.height / 2 - SVRT.sizeDelta.y / 2 + SVRT.anchoredPosition.y, SVRT.sizeDelta.x - verticalScrollbar_weight, SVRT.sizeDelta.y);
            //Rect rect_int = new Rect(420, 166.5f, 1365, SVRT.sizeDelta.y);
            Rect rect_int = new Rect(420, vec.x, vec.y, SVRT.sizeDelta.y);

            var tex_int = CaptureScreenshot(rect_int, i + "");

            //合成
            colors = tex_int.GetPixels32(0);
            if (i > 0)
            {
                y -= tex_int.height;
            }
            else
            {
                y = totalHeight - tex_int.height;
            }
            endTex.SetPixels32(x, y, tex_int.width, tex_int.height, colors);
        }

        //小数倍的截图
        ContentRT.anchoredPosition = new Vector2(0, SV_Y * (mult - 1));
        yield return new WaitForEndOfFrame();
        //Rect rect_float = new Rect(Screen.width / 2 - SVRT.sizeDelta.x / 2 + SVRT.anchoredPosition.x, Screen.height / 2 - SVRT.sizeDelta.y / 2 + SVRT.anchoredPosition.y, SVRT.sizeDelta.x - verticalScrollbar_weight, SVRT.sizeDelta.y * mult_float);
        Rect rect_float = new Rect(420, vec.x, vec.y, SVRT.sizeDelta.y * mult_float);

        var tex_float = CaptureScreenshot(rect_float, "end");

        //合成
        colors = tex_float.GetPixels32(0);
        y -= tex_float.height;
        endTex.SetPixels32(x, y, tex_float.width, tex_float.height, colors);
        endTex.Apply();
        byte[] bytes = endTex.EncodeToPNG();//然后将这些纹理数据,成一个png图片文件
        var strPng = Convert.ToBase64String(bytes);

#if UNITY_EDITOR
        string filename = Application.dataPath + "/PNG/合成.png";
        System.IO.File.WriteAllBytes(filename, bytes);
        Debug.Log(string.Format("截屏了一张图片: {0}", filename));
#endif

        SVRT.GetComponent<ScrollRect>().verticalNormalizedPosition = 1;
        CapCallBack?.Invoke(strPng);

        CapByteCallBack?.Invoke(bytes);
    }

    /// <summary>
    /// 开始截图
    /// </summary>
    /// <returns>The screenshot2.</returns>
    /// <param name="rect">Rect.截图的区域,左下角为o点</param>
    private Texture2D CaptureScreenshot(Rect rect, string name)
    {
        //Debug.Log(rect.ToString());
        Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGBA32, false);//先创建一个的空纹理,大小可根据实现需要来设置
        screenShot.ReadPixels(rect, 0, 0);//读取屏幕像素信息并存储为纹理数据,
        screenShot.Apply();

#if UNITY_EDITOR
        byte[] bytes = screenShot.EncodeToPNG();//然后将这些纹理数据,成一个png图片文件
        string filename = Application.dataPath + "/PNG/Screenshot" + name + ".png";
        System.IO.File.WriteAllBytes(filename, bytes);
        //Debug.Log(string.Format("截屏了一张图片: {0}", filename));
#endif
        return screenShot;
    }
}

3.web端代码

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>XiaoLuoDai</title>
    <link rel="shortcut icon" href="TemplateData/favicon.ico">
    <link rel="stylesheet" href="TemplateData/style.css">
    <script src="TemplateData/UnityProgress.js"></script>
    <script src="Build/UnityLoader.js"></script>
    <script>
	
      var unityInstance = UnityLoader.instantiate("unityContainer", "Build/WebGL.json", {onProgress: UnityProgress});
	  
	   function GetWebGLURI()
        {
        unityInstance.SendMessage("CQOOC", "GetURI_CallBack", window.location.href);
        }
    </script>
	 <script src="https://cdn.bootcss.com/jspdf/1.3.4/jspdf.debug.js"></script>
	<script>
	  function downloadPng(base64, filename) {
	      var baseData = 'data:image/png;base64,' + base64
	          ///
	          // 获取图片文件的宽高
	          ///
	          let image = new Image();
	      image.src = baseData;
	      image.onload = function () {
	          console.log(image.width, image.height);
	          var contentWidth = image.width;
	          var contentHeight = image.height;

	          //一页pdf显示html页面生成的canvas高度;
	          var pageHeight = contentWidth / 592.28 * 841.89;
	          //未生成pdf的html页面高度
	          var leftHeight = contentHeight;
	          //页面偏移
	          var position = 0;
	          //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
	          var imgWidth = 595.28;
	          var imgHeight = 592.28 / contentWidth * contentHeight;
	          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
	          //当内容未超过pdf一页显示的范围,无需分页

	          var pdf = new jsPDF('', 'pt', 'a4');
	          if (leftHeight < pageHeight) {
	              pdf.addImage(baseData, 'PNG', 0, 0, imgWidth, imgHeight);
	          } else {
	              while (leftHeight > 0) {
	                  pdf.addImage(baseData, 'PNG', 0, position, imgWidth, imgHeight)
	                  leftHeight -= pageHeight;
	                  position -= 841.89;
	                  //避免添加空白页
	                  if (leftHeight > 0) {
	                      pdf.addPage();
	                  }
	              }
	          }
	          pdf.save(filename + ".pdf")
	      }
	  }
	</script>
<script>
      function FullScreenMetthod()//中文输入
	  {
		document.getElementById('unityContainer').requestFullscreen();
	  }
  </script>
  </head>
  <body>
    <div class="webgl-content">
      <div id="unityContainer" style="width: 1920px; height: 1080px"></div>
      <div class="footer">
        <div class="webgl-logo"></div>
        <div class="fullscreen" onclick="FullScreenMetthod()"></div>
        <div class="title">XiaoLuoDai</div>
      </div>
    </div>
  </body>
</html>

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

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

相关文章

2023_Spark_实验十八:安装FinalShell

下载安装包 链接&#xff1a;https://pan.baidu.com/s/14cOJDcezzuwUYowPsOA-sg?pwd6htc 提取码&#xff1a;6htc 下载文件名称&#xff1a;FinalShell.zip 二、安装 三、启动FinalShell 四、连接远程 linux 服务器 先确保linux系统已经开启&#xff0c;不然连接不上 左边…

Linux离线安装Apache HTTP

准备工作 下载apr、apr-util、pcre、httpd包 apr、apr-util下载, 如下图: pcre下载,如下图: httpd下载 ,如下图: 开始安装 1. 安装编译apr [rootlocalhost ~]# cd /usr/local [rootlocalhost local]# tar -zxvf apr-1.7.4.tar.gz -C ./ [rootlocalhost local]# cd apr…

apple pencil买不买?ipad第三方电容笔推荐

相信很多学生党的学习都离不开iPad&#xff0c;然而电容笔&#xff0c;自然也是是必不可少的。至于真的Apple Pencil&#xff0c;那就更贵了&#xff0c;一支就要一千多块钱&#xff0c;普通人可买不起。国内的电容笔已经做得很好了&#xff0c;虽然不像苹果原装电容笔那样&…

186_Power BI Desktop 支持计算组编辑

186_Power BI Desktop 支持计算组编辑 一、背景 今天是2023年10月16日&#xff0c;基本上是 Power BI 每月更新的时间点了。打开看到 Power BI 果然已经更新到了2023年10月版本&#xff1a;2.122.746.0 (23.10) (x64) 这里提一下&#xff0c;我使用的是商店版的 Power BI De…

多线程中ThreadPoolExecutor.map()中传递多个参数

with concurrent.futures.ThreadPoolExecutor(max_threads) as executor:results executor.map(get_captcha_image, ip_addrs, [img_url] * len(ip_addrs)) #要传入多个参数时&#xff0c;每个参数都得是固定相同长度的可迭代对象# 收集结果for result in results:print(resul…

便利店小程序可以做哪些营销活动呢

在当今这个数字化时代&#xff0c;微信小程序已经成为了人们日常生活的一部分。对于便利店来说&#xff0c;拥有一个优秀的小程序不仅可以提高销售&#xff0c;还可以扩大品牌影响力&#xff0c;增加客户粘性。本文将探讨便利店小程序可以做什么样的营销活动&#xff0c;如何利…

智慧饭堂报餐系统源码 智慧食堂源码

智慧饭堂报餐系统源码 智慧食堂源码 技术栈 1、前端技术栈&#xff1a;ES6、vue、vuex、vue-router、vue-cli、axios、element-ui 2、后端技术栈&#xff1a;SpringBoot、MyBatis、Spring Security、Jwt 介绍 一款java开发的智慧饭堂报餐系统&#xff0c;支持连接人脸识别…

分享一下微信报名系统怎么做

微信报名系统是一种基于微信公众号或小程序的开发和应用&#xff0c;可实现用户通过微信进行在线报名、支付等操作的系统。本文将介绍微信报名系统的基本概念、制作流程、功能特点、使用流程和推广策略&#xff0c;帮助读者了解如何制作一个高效的微信报名系统。 一、微信报名系…

从零开始学习调用百度地图网页API:三、鼠标点击绘图功能

目录 代码功能问题注意addEventListenerplot_line 代码 <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><meta name"viewport" content"initial-scale1.0,…

WordPress 常规设置页面调用媒体中心上传图片插入URL(新版可用)

首先&#xff0c;我们需要在主题或插件文件夹中创建一个 JavaScript 文件&#xff08;如&#xff1a;media-uploader.js&#xff09;&#xff0c;该文件中包含如下代码。 /*** 媒体中心上传 js **/ jQuery(document).ready(function($){var mediaUploader;$(#upload_image_but…

AUTOSAR介绍

AUTOSAR产生背景 车辆功能的创新导致车辆E/E架构日益复杂。与此同时&#xff0c;开发要求通常自相矛盾&#xff1a;例如要求驾驶域辅助系统支持关键性驾驶操控&#xff0c;提高燃油经济性同时符合环境标准。信息娱乐和通信系统与实时车辆环境和在线服务的不断深入整合带来了更…

MASA MAUI 预览Office文件

文章目录 背景介绍1、新建MAUI Blazor项目2、创建OfficeViewer.razor组件3、使用安卓模拟器运行4、兼容iOS 总结 背景 接到一个在Maui中预览Office文件的需求&#xff0c;包含excel、word、PDF三种常见的文件&#xff0c;经过技术选型&#xff0c;最后选择了微软原生支持的off…

如何避免输入中文拼音时触发input事件

如何避免输入中文拼音时触发 input 事件 html 结构 <input type"text" name"" id"" />js 定义了一个输入框并添加了三个事件监听器。以下是每个部分的解释&#xff1a; const input document.querySelector("input"); let i…

记一次U8登录异常问题

最近陆续有同事反映U8系统登录切换不同用户&#xff0c;在选择账套时U8长时间无反应。 一开始在经历二十多秒的等待后还会出现账套下拉列表选项&#xff0c;后来经历更长的时间等待后提示连接SQL服务器错误&#xff0c;如下图&#xff1a; 因为不切换用户时直接登录使用是没有…

leetcode-1.两数之和

1. 题目 2. 解答 遍历数组元素之和&#xff0c;由于只有唯一答案&#xff0c;并且数组中同一个元素不能重复出现&#xff0c; 因此可以使用双重遍历方式来计算所有可能&#xff1b; #include <stdio.h>void solve(int num[], int len, int target) {for (int i 0; i …

spring 注解: 更加简单的存储 Bean

目录 1. 更加简单的存储 Bean 1.1 添加注解 1.1.1 Controller【控制器存储】 1.1.2 Service【服务存储】 1.1.3 Repository【仓库存储】 1.1.4 Component【组件存储】 1.1.5 Configuration【配置存储】 1.1.6 类注解存储 Bean 的命名规则&#xff08;默认命名规则&…

浅谈精密配电多回路监控装置在轨道交通项目上的应用

安科瑞 须静燕 行业背景 轨道交通作为城市公共交通系统的一部分&#xff0c;在过去几十年中得到了广泛的发展和扩张。它在解决城市交通拥堵、减少环境污染、提高城市可持续性等方面发挥了重要作用。随着科技的进步&#xff0c;轨道交通系统也在不断引入新的技术和创新&#xff…

外汇天眼:本周监管警告名单更新,远离以下平台!

监管信息早知道&#xff01;外汇天眼将每周定期公布监管牌照状态发生变化的交易商&#xff0c;以供投资者参考&#xff0c;规避投资风险。如果平台天眼评分过高&#xff0c;建议投资者谨慎选择&#xff0c;因为在外汇天眼评分高不代表平台没问题&#xff01; 以下是监管牌照发生…

出差学知识No4:ubuntu vim中的各种必须掌握的经典操作(持续更新......)

1、给vim模式下打开的文档内容每行之前加上行号&#xff0c;便于问题定位 1、给vim模式下打开的文档内容每行之前加上行号&#xff0c;便于问题定位 摁一下Esc之后输入&#xff1a;set number

CentoS7 安装篇十二:mysql主从搭建(xtrackbackup不停机搭建)

一、mysql主从搭建使用mysql自身自己做&#xff0c;需要停止mysql服务进行&#xff0c;这种情况下面临以下问题 1.影响客户正在运行的软件&#xff0c;数据库比较大的情况下耗时时间长 2.如果不想影响客户使用体验&#xff0c;就是晚上加班搞 为了更好软件体验及避免加班情况&a…