Unity (WebGL) stitch screenshots and save them locally, download PDF

Table of Contents

1. Call the code

2. Screenshot puzzle code


Screenshot reference: Unity3D partial screenshot, full screen screenshot, and UI screenshot three methods_unity screenshot_wildland dragon hunting blog-CSDN blog

Document download: Unity WebGL generates doc and saves it to the local computer_unity webgl saves the file_The blog of catching dragons as pets in the wild-CSDN blog

Chinese input: Unity WebGL Chinese input supports input method following and supports full screen (with Dome included)_unity Chinese plug-in-CSDN blog

1.Call code

Without further ado, let’s get straight to the code:

 private void Awake()
    {
//Click the submit download button
        Btn_download.onClick.AddListener(() =>
        {
            Btn_download.gameObject.SetActive(value: false);

            GetComponent<Capture_Long>().Cap_LongTex();//Screenshot puzzle
//Download 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);//Call webgl method

              // Debug.Log("filename=" + filename);
            });
//Upload screenshot
            GetComponent<Capture_Long>().CapByteCallBack = ((png_byte) =>
            {
                string filename = CQOOC.Instance.userName + "_" + DateTime.Now.ToString("g");
                Debug.Log("filename=" + filename);
                //Upload experiment report screenshot
                CQOOC.Instance.UploadFile(png_byte, filename + ".png", ((b) => {
                    if(b)
                    {
                        Debug.Log("Uploaded screenshot successfully!");
                    }
                    else
                    {
                        Debug.Log("Failed to upload screenshot!");
                    }
                }));

                //Upload experiment report data
                CQOOC.Instance.UploadData_((b) => {
                    if(b)
                    {
                        UITipDialogMini.Instance.SetState(true, "Submit data successfully!");
                    }
                    else
                    {
                        UITipDialogMini.Instance.SetState(true, "Failed to submit data!");
                    }
                });

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

        DateTime now02 = DateTime.Now;
        string formattedTime02 = now02.ToString("yyyy year M month d day 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. Screenshot puzzle code

The picture needs to be spliced because it is too long

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>
    /// Connect long pictures and splice them
    /// </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)
    {
        //Height in canvas 950
        float SV_Y = SVRT.sizeDelta.y;

        //The height of the area displayed by content is 0
        float Content_Y = ContentRT.anchoredPosition.y;
        //The overall height of the picture is 2660
        float Content_Height = contentRT.sizeDelta.y + SV_Y;

        var mult = (float)(Content_Height / SV_Y);
        //integer multiple
        int mult_int = (int)mult;
        //Last decimal multiple
        float mult_float = mult - mult_int;

        //Scroll bar width
        float verticalScrollbar_weight = SVRT.GetComponent<ScrollRect>().verticalScrollbar.GetComponent<RectTransform>().sizeDelta.x;

        yield return new WaitForEndOfFrame();

        //The total height of the composite image
        int totalHeight = (int)Content_Height;
        Texture2D endTex = new Texture2D((int)vec.y, totalHeight, TextureFormat.RGBA32, false);
        int x = 0, y = 0;
        Color32[] colors;

        //Screenshots of integer multiples
        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 + "");

            //synthesis
            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);
        }

        //Screenshots of decimal multiples
        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");

        //synthesis
        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();//Then convert these texture data into a png image file
        var strPng = Convert.ToBase64String(bytes);

#if UNITY_EDITOR
        string filename = Application.dataPath + "/PNG/composite.png";
        System.IO.File.WriteAllBytes(filename, bytes);
        Debug.Log(string.Format("Screenshot a picture: {0}", filename));
#endif

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

        CapByteCallBack?.Invoke(bytes);
    }

    /// <summary>
    /// Start taking screenshots
    /// </summary>
    /// <returns>The screenshot2.</returns>
    /// <param name="rect">Rect. The area of the screenshot, the lower left corner is point 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);//Create an empty texture first, the size can be set according to implementation needs
        screenShot.ReadPixels(rect, 0, 0);//Read screen pixel information and store it as texture data,
        screenShot.Apply();

#if UNITY_EDITOR
        byte[] bytes = screenShot.EncodeToPNG();//Then convert these texture data into a png image file
        string filename = Application.dataPath + "/PNG/Screenshot" + name + ".png";
        System.IO.File.WriteAllBytes(filename, bytes);
        //Debug.Log(string.Format("Screenshot a picture: {0}", filename));
#endif
        return screenShot;
    }
}

3.Web side code

<!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>
\t
      var unityInstance = UnityLoader.instantiate("unityContainer", "Build/WebGL.json", {onProgress: UnityProgress});
\t  
function GetWebGLURI()
        {
        unityInstance.SendMessage("CQOOC", "GetURI_CallBack", window.location.href);
        }
    </script>
<script src="//i2.wp.com/cdn.bootcss.com/jspdf/1.3.4/jspdf.debug.js"></script>
<script>
function downloadPng(base64, filename) {
var baseData = 'data:image/png;base64,' + base64
///
// Get the width and height of the image file
///
let image = new Image();
image.src = baseData;
image.onload = function () {
console.log(image.width, image.height);
var contentWidth = image.width;
var contentHeight = image.height;

//One page of pdf displays the canvas height generated by the html page;
var pageHeight = contentWidth / 592.28 * 841.89;
//The html page height of the pdf is not generated
var leftHeight = contentHeight;
//Page offset
var position = 0;
//The size of a4 paper [595.28,841.89], the width and height of the canvas generated by the html page in the pdf image
var imgWidth = 595.28;
var imgHeight = 592.28/contentWidth * contentHeight;
//There are two heights that need to be distinguished, one is the actual height of the html page, and the page height of the generated pdf (841.89)
//When the content does not exceed the range displayed on one PDF page, no paging is required

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;
//Avoid adding blank pages
if (leftHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(filename + ".pdf")
}
}
</script>
<script>
      function FullScreenMetthod()//Chinese input
{
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>