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

截图参考: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();//截图拼图
//下载PDFGetComponent<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){//画布中的高度      950float SV_Y = SVRT.sizeDelta.y;//content显示的区域高度   0float Content_Y = ContentRT.anchoredPosition.y;//图片的整体高度   2660float 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_EDITORstring filename = Application.dataPath + "/PNG/合成.png";System.IO.File.WriteAllBytes(filename, bytes);Debug.Log(string.Format("截屏了一张图片: {0}", filename));
#endifSVRT.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_EDITORbyte[] bytes = screenShot.EncodeToPNG();//然后将这些纹理数据,成一个png图片文件string filename = Application.dataPath + "/PNG/Screenshot" + name + ".png";System.IO.File.WriteAllBytes(filename, bytes);//Debug.Log(string.Format("截屏了一张图片: {0}", filename));
#endifreturn 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.rhkb.cn/news/164790.html

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

相关文章

福昕阅读器打开pdf文档时显示的标题不是文件名

0 Preface/Foreword 1 现象 文件名为&#xff1a;Demo-20231017 打开效果&#xff1a;显示名字为 word template 2 解决方法 2.1 利用打印方式将word生产pdf 在word生成pdf文件时&#xff0c;使用打印方式生成pdf文档。 2.2 删除word文档设置的标题 文件---》信息---》标…

推荐《全职猎人》

电视动画《全职猎人》是由MADHOUSE公司制作的长篇电视动画&#xff0c;改编自日本漫画家富坚义博创作的同名漫画。该动画于2011年10月2日—2014年9月23日在日本电视网协议会首播&#xff0c;全148话。 剧场版动画《全职猎人&#xff1a;绯色的幻影》和《全职猎人&#xff1a;最…

计算机缺失d3dcompiler_47.dll解决方案,如何修复电脑缺失d3d文件

在计算机系统中&#xff0c;DLL文件&#xff08;动态链接库&#xff09;是一种重要的共享库&#xff0c;它包含了可被多个程序使用的代码和数据。然而&#xff0c;当某些DLL文件丢失或损坏时&#xff0c;可能会导致程序无法正常运行。本文将介绍四种解决D3DCompiler_47.dll缺失…

二、vue基础语法

一、模板语法 1、文本渲染 使用双花括号语法插入文本 <template><div><h3>msg: {{ message }}</h3></div> </template><script> export default {data() {return {message: "输出信息"}} } </script><style s…

C语言柔性数组

大家好&#xff0c;我们今天来补充一个知识&#xff0c;就是柔性数组。 柔性数组概念&#xff1a; 也许你从来没有听说过柔性数组&#xff08;flexible array&#xff09;这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff0c;结构中的最后一个元素允许是未知大小的数…

隐式类型转换

什么是隐式类型转换&#xff0c;多参数的造函数隐式类型转换&#xff0c;和单参数的构造函数隐式类型转换有什么区别 C中有三种主要的隐式类型转换&#xff1a; 1:多参数的构造函数隐式类型转换 2:单参数的构造函数隐式类型转换 3:成员函数隐式类型转换。…

【企业级SpringBoot单体项目模板 】—— 项目代码管理

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;SpringBoot项目模版、企业级、模版、代码管理☀️每日 一言&#xff1a;生命力顽强的种子&#xff0c;从不对瘠土唱诅咒的歌。 文章目录 一、第一种&#xff1a;先创建仓库1.1 创建仓库1.2 clone…

黑白棋(Othello, ACM/ICPC World Finals 1992, UVa220)rust解法

你的任务是模拟黑白棋游戏的进程。黑白棋的规则为&#xff1a;黑白双方轮流放棋子&#xff0c;每次必须让新放的棋子“夹住”至少一枚对方棋子&#xff0c;然后把所有被新放棋子“夹住”的对方棋子替换成己方棋子。一段连续&#xff08;横、竖或者斜向&#xff09;的同色棋子被…

jvm的jshell,学生的工具

jshell 在我眼里&#xff0c;只能作为学校教学的一个玩具&#xff0c;事实上官方也做了解释&#xff0c;以下是官方的解释&#xff1a; 在学习编程语言时&#xff0c;即时反馈很重要&#xff0c;并且 它的 API。学校引用远离Java的首要原因 教学语言是其他语言有一个“REPL”…

【C++】:类和对象(中)之类的默认成员函数——构造函数and析构函数

1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生成…

全波形反演培训的思考与总结

一. InversionNet 最简单的端到端DL_FWI 1. 网络结构&#xff1a; 图1 构建了一个具有编码器-解码器结构的卷积神经网络&#xff0c;根据地震波动数据模拟地下速度结构。编码器主要由卷积层构建&#xff0c;它从输入地震数据中提取高级特征并将其压缩为单个高维向量。解码器然后…

谷歌云:下一代开发者和企业解决方案的强力竞争者

自从2018年Oracle前研发总裁Thomas Kurian加入谷歌云&#xff08;Google Cloud&#xff09;并出任谷歌云CEO以来&#xff0c;业界对于谷歌云的发展就十分好奇。而谷歌云的前任CEO Diane Greene曾是VMware的创始人之一&#xff0c;那么两任企业级技术和解决方案出身的CEO&#x…

代码随想录算法训练营第五十五天 | 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

300.最长递增子序列 视频讲解&#xff1a;动态规划之子序列问题&#xff0c;元素不连续&#xff01;| LeetCode&#xff1a;300.最长递增子序列_哔哩哔哩_bilibili 代码随想录 &#xff08;1&#xff09;代码 674. 最长连续递增序列 视频讲解&#xff1a;动态规划之子序列问题…

前端学成在线项目详细解析一

学成在线项目 01-项目目录 网站根目录是指存放网站的第一层文件夹&#xff0c;内部包含当前网站的所有素材&#xff0c;包含 HTML、CSS、图片、JavaScript等等。 首页引入CSS文件 <!-- 顺序要求&#xff1a;先清除再设置 --> <link rel"stylesheet" hre…

Vue非单文件组件

组件就是用来实现局部特定功能效果的代码集合&#xff0c;为的就是复用编码&#xff0c;简化项目编码&#xff0c;提高运行效率。 组件分为非单文件组件和单文件组件&#xff0c;这里介绍的是非单文件组件。 一、创建组件 创建组件的语法格式如下&#xff1a; const 组件名 …

微信小程序开发之自定义组件(会议OA项目其他页面搭建)

目录 前言 一、WeChat中的自定义组件 1. 基本概述 2. 包含文件及作用 3. 自定义组件的作用 4.使用步骤&#xff1a; 二、tabs组件及会议管理布局 tabs组件 1. 创建组件 准备 创建 使用组件 会议管理布局 tabs.wxml指定组件模版 tabs.wxss完成样式设计 tabs.js定义属…

柔性数组的使用及注意事项

1.柔性数组在结构体当中,并且在结构体的最后面. 2.结构体中除了柔型数组外至少还要有一个其他成员. 3.sizeof()返回结构体的大小不包含柔性数组的大小. 4.malloc 例:struct sdshdr16 *p malloc(sizeof (struct sdshdr16) 32); // 32 为柔性数组的大小 5.free 例: fre…

讲解 CSS 过渡和动画 — transition/animation (很全面)

前言 由于用户越来越注重 Web应用 的使用体验&#xff0c;随之而来的是 Web应用 需要提供了更加完善的 Web 动画 效果来实现以平滑的状态贯穿于用户的整个使用过程中。现在&#xff0c;这已经是司空见惯了&#xff0c;用户潜意识是希望可以获得更快的反馈响应和更友好的用户界…

Python用selenium实现自动登录和下单的项目实战

本文主要介绍了Python用selenium实现自动登录和下单的项目实战&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧− 前言 学python对selenium应该不陌生吧 Selenium…

轻量级导出 Excel 标准格式

一般业务系统中都有导出到 Excel 功能&#xff0c;其实质就是把数据库里面一条条记录转换到 Excel 文件上。Java 常用的第三方类库有 Apache POI 和阿里巴巴开源的 EasyExcel 等。另外也有通过 Web 模板技术渲染 Excel 文件导出&#xff0c;这实质是 MVC 模式的延伸&#xff0c…