Unity获取剪切板内容粘贴板图片文件文字

最近做了一个发送消息的unity项目,需要访问剪切板里面的图片文字文件等,翻遍了网上的东西,看了不是需要导入System.Windows.Forms(关键导入了unity还不好用,只能用在纯c#项目中),所以我看了下pyhton是否有比较好的,结果是可以用的,把项目打包成了exe,unity去调用这个exe就行了。代码如下`using System;

using UnityEngine;

using UnityEngine.UI;

using System.Diagnostics;

using System.IO;

using System.Text;

public class HelpPCon : MonoBehaviour

{

[SerializeField]

///

/// 图片信息父物体

///

Transform PicParent_N;

[SerializeField]
/// <summary>
/// 消息Content
/// </summary>
GameObject MsgContent_N;

/// <summary>
/// 文字信息消息预设
/// </summary>
[SerializeField]
GameObject msgTxtPrfab;

/// <summary>
/// 图片信息消息预设
/// </summary>
[SerializeField]
GameObject msgTexturePrfab;
/// <summary>
/// 下方消息框
/// </summary>
[SerializeField]
InputField IFDDownMsg_N;
[SerializeField]
Button BtnHelpSend_N;
[SerializeField]
public Button BtnZhanTie_N;
void Awake()
{
    // 添加发送帮助数据按钮点击事件
    BtnHelpSend_N.onClick.AddListener(SendHelpData);
    // 添加粘贴数据按钮点击事件
    BtnZhanTie_N.onClick.AddListener(GetClipboardData);
}

private void OnEnable()
{
    // 当界面激活时隐藏图片内容
    HideTextureContant();
}

private void Update()
{
    // 监听按下 Ctrl + V,触发粘贴数据操作
    if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.V))
    {
        GetClipboardData();
    }
}

/// <summary>
/// 获取剪贴板数据,根据数据类型处理不同的操作
/// </summary>
void GetClipboardData()
{
    GetClipboardData((str) =>
    {
        // 解析剪贴板数据
        ClipboardData clipboardData = MessageDataProxy.Single.GetClipData(str);
        switch (clipboardData.type)
        {
            case "TEXT":
                // 如果是文本类型,则将文本显示在消息框中
                IFDDownMsg_N.text = Encoding.UTF8.GetString(clipboardData.data);
                break;
            case "IMAGE":
                // 如果是图片类型,则显示图片
                PicParent_N.gameObject.SetActive(true);
                for (int i = 0; i < PicParent_N.childCount; i++)
                {
                    // 找到未激活的子对象,加载图片数据并显示
                    if (PicParent_N.GetChild(i).gameObject.activeSelf == false)
                    {
                        PicParent_N.GetChild(i).GetComponent<RawImage>().texture = MessageDataProxy.Single.GetTextureFromByte(clipboardData.data);
                        PicParent_N.GetChild(i).gameObject.SetActive(true);
                        break;
                    }
                }
                break;
            case "FILE_LIST":
                // 如果是文件列表类型,则尝试加载文件为图片
                MessageDataProxy.Single.LoadTextureFromFile(clipboardData.data, (b, t) =>
                {
                    if (b)
                    {
                        // 加载成功则显示图片
                        PicParent_N.gameObject.SetActive(true);
                        for (int i = 0; i < PicParent_N.childCount; i++)
                        {
                            if (PicParent_N.GetChild(i).gameObject.activeSelf == false)
                            {
                                PicParent_N.GetChild(i).GetComponent<RawImage>().texture = t;
                                PicParent_N.GetChild(i).gameObject.SetActive(true);
                                break;
                            }
                        }
                    }
                    else
                    {
                        // 加载失败,输出错误信息
                        UnityEngine.Debug.LogError("粘贴板上的文件不是图片格式");
                    }
                });
                break;
            default:
                break;
        }
    });
}

/// <summary>
/// 获取剪贴板数据,并通过回调函数返回结果
/// </summary>
/// <param name="callback">处理剪贴板数据的回调函数</param>
void GetClipboardData(Action<string> callback)
{
    // 执行外部程序获取剪贴板数据的路径
    string pythonScriptPath = Application.streamingAssetsPath + "/ReadTex/ReadTex.exe";
    // 创建一个进程启动信息对象
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.FileName = pythonScriptPath;
    startInfo.UseShellExecute = false;
    startInfo.RedirectStandardOutput = true;
    startInfo.CreateNoWindow = true;
    using (Process process = Process.Start(startInfo))
    {
        // 等待并获取输出
        using (StreamReader reader = process.StandardOutput)
        {
            string result = reader.ReadToEnd();
            callback?.Invoke(result); // 调用回调函数返回获取的剪贴板数据
        }
    }
}

/// <summary>
/// 隐藏图片内容的容器及其子对象
/// </summary>
void HideTextureContant()
{
    PicParent_N.gameObject.SetActive(false);
    for (int i = 0; i < PicParent_N.childCount; i++)
    {
        PicParent_N.GetChild(i).gameObject.SetActive(false);
    }
}

/// <summary>
/// 当所有子物体都隐藏时,隐藏自身容器
/// </summary>
public void HideSelfIfChildHide()
{
    for (int i = 0; i < PicParent_N.childCount; i++)
    {
        if (PicParent_N.GetChild(i).gameObject.activeSelf)
        {
            return;
        }
    }
    PicParent_N.gameObject.SetActive(false);
}

/// <summary>
/// 发送反馈消息,将文本和图片信息添加到消息内容中
/// </summary>
void SendHelpData()
{
    // 添加文本消息
    if (!string.IsNullOrEmpty(IFDDownMsg_N.text))
    {
        GameObject msgTxt = GameObject.Instantiate(msgTxtPrfab);
        msgTxt.transform.SetParent(MsgContent_N.transform);
        msgTxt.GetComponent<Text>().text = IFDDownMsg_N.text;
        IFDDownMsg_N.text = "";
    }

    // 添加图片消息
    for (int i = 0; i < PicParent_N.childCount; i++)
    {
        if (PicParent_N.GetChild(i).gameObject.activeSelf)
        {
            GameObject msgTexture = GameObject.Instantiate(msgTexturePrfab);
            msgTexture.transform.SetParent(MsgContent_N.transform);
            msgTexture.GetComponent<RawImage>().texture = PicParent_N.GetChild(i).GetComponent<RawImage>().texture;
        }
    }

    // 发送完成后隐藏图片内容
    HideTextureContant();
}

}

using System;

using System.IO;

using System.Text;

using UnityEngine;

[System.Serializable]

public class ClipboardData

{

public string type; // 类型字段,用于标识数据类型

public byte[] data; // 数据字节数组

}

public class MessageDataProxy

{

static MessageDataProxy Single_;

public static MessageDataProxy Single

{

get

{

if (Single_ == null)

Single_ = new MessageDataProxy();

return Single_;

}

}

/// <summary>
/// 从JSON数据中获取剪贴板数据对象
/// </summary>
/// <param name="jsondata">JSON格式的数据字符串</param>
/// <returns>剪贴板数据对象</returns>
public ClipboardData GetClipData(string jsondata)
{
    ClipboardData clipboardData = JsonUtility.FromJson<ClipboardData>(jsondata);
    return clipboardData;
}

/// <summary>
/// 从字节数组中加载Texture2D对象
/// </summary>
/// <param name="imageBytes">图像的字节数组数据</param>
/// <returns>加载后的Texture2D对象</returns>
public Texture2D GetTextureFromByte(byte[] imageBytes)
{
    Texture2D texture = new Texture2D(1, 1); // 创建一个空的Texture2D对象
    texture.LoadImage(imageBytes); // 加载图像数据到Texture2D
    return texture;
}

/// <summary>
/// 从文件中异步加载Texture2D对象,并通过回调函数返回结果
/// </summary>
/// <param name="imageBytes">文件路径的字节数组数据</param>
/// <param name="callback">加载完成后的回调函数,参数为是否成功加载和加载后的Texture2D对象</param>
public void LoadTextureFromFile(byte[] imageBytes, Action<bool, Texture2D> callback)
{
    string path = Encoding.UTF8.GetString(imageBytes); // 解析字节数组为文件路径字符串
    if (path.EndsWith(".png") || path.EndsWith(".jpg"))
    {
        callback?.Invoke(true, LoadTextureFromFile(path)); // 如果路径合法,异步加载并调用回调函数
    }
    else
    {
        callback?.Invoke(false, null); // 如果路径不合法,调用回调函数返回加载失败
    }
}

/// <summary>
/// 从指定路径加载Texture2D对象
/// </summary>
/// <param name="path">图像文件路径</param>
/// <returns>加载后的Texture2D对象</returns>
public Texture2D LoadTextureFromFile(string path)
{
    // 读取本地文件数据
    byte[] fileData = File.ReadAllBytes(path);
    // 创建一个新的Texture2D对象
    Texture2D texture = new Texture2D(2, 2);
    // 将图片字节流数据加载到Texture2D对象中
    texture.LoadImage(fileData);
    // 返回Texture2D对象
    return texture;
}

}

python代码如下`import win32clipboard

import json

import logging

import os

from PIL import Image

import io

设置日志记录

logging.basicConfig(filename='clipboard_data.log', level=logging.DEBUG,

format='%(asctime)s %(levelname)s %(message)s')

clipboard_type_map = {

win32clipboard.CF_UNICODETEXT: "TEXT",

win32clipboard.CF_DIB: "IMAGE",

win32clipboard.CF_HDROP: "FILE_LIST",

}

def get_clipboard_data():

try:

win32clipboard.OpenClipboard()

data = None

for clip_type in clipboard_type_map.keys():

try:

data = win32clipboard.GetClipboardData(clip_type)

if data:

data = (clipboard_type_map[clip_type], data)

break

except Exception as e:

logging.error(f"Error retrieving clipboard data: {e}")

pass

win32clipboard.CloseClipboard()

if data is None:

logging.warning("No data found in clipboard.")

return ('UNKNOWN', None)

return data

except Exception as e:

logging.error(f"Clipboard operation failed: {e}")

return ('UNKNOWN', None)

获取剪切板中的内容

clipboard_data = get_clipboard_data()

在控制台打印 JSON 数据

if clipboard_data[0] == 'TEXT':

non_utf8_string = clipboard_data[1]

utf8_bytes = non_utf8_string.encode('utf-8')

将字节数据转换为整数数组

byte_list = list(utf8_bytes)

text_json = {

'type': 'TEXT',

'data': byte_list

}

print(json.dumps(text_json, ensure_ascii=False, indent=4))

elif clipboard_data[0] == 'IMAGE':

byte_data = clipboard_data[1]

byteio = io.BytesIO(byte_data)

image = Image.open(byteio)

将字节数据转换为整数数组

file_name = 'clipboard_image.png' # 图片文件名,这里可以根据需要修改

获取当前脚本文件的路径

current_dir = os.path.dirname(os.path.abspath(file ))

构建保存图片的完整路径

file_path = os.path.join(current_dir, file_name)

image.save(file_path)

with open(file_path, "rb") as img_file:

byte_data = list(img_file.read())

image_json = {

'type': 'IMAGE',

'data': byte_data

}

print(json.dumps(image_json, ensure_ascii=False, indent=4))

elif clipboard_data[0] == 'FILE_LIST':

non_utf8_string = clipboard_data[1][0]

utf8_bytes = non_utf8_string.encode('utf-8')

将字节数据转换为整数数组

byte_list = list(utf8_bytes)
file_list_json = {
    'type': 'FILE_LIST',
    'data': byte_list
}
print(json.dumps(file_list_json, ensure_ascii=False, indent=4))

else:

unknown_json = {

'type': 'UNKNOWN',

'data': None

}

print(json.dumps(unknown_json, ensure_ascii=False, indent=4))如果不会pyhton的可以点击获取源码

`

相关推荐
吴梓穆43 分钟前
Unity EasyAR入门教程
unity
两水先木示7 小时前
【Unity3D】ECS入门学习(七)缓存区组件 IBufferElementData
学习·unity·ecs
EQ-雪梨蛋花汤9 小时前
【WebAR-图像跟踪】在Unity中基于Imagine WebAR实现AR图像识别
unity·游戏引擎·ar
Thinbug9 小时前
UE(虚幻)学习(三) UnrealSharp插件中调用非托管DLL
游戏引擎·虚幻
子燕若水9 小时前
UE(虚幻引擎)运行项目时缺少插件/摸块,需要手动编译
游戏引擎·虚幻
向宇it11 小时前
【从零开始入门unity游戏开发之——C#篇32】C#其他不常用的泛型数据结构类、顺序存储和链式存储
java·开发语言·数据结构·unity·c#·游戏引擎
虾球xz15 小时前
游戏引擎学习第64天
redis·学习·游戏引擎
虾球xz16 小时前
游戏引擎学习第63天
学习·游戏引擎
两水先木示16 小时前
【Unity3D】ECS入门学习(六)状态组件 ISystemStateComponentData
学习·unity·ecs
Thomas_YXQ16 小时前
Unity3D Huatuo:划时代的原生C#热更新技术详解
开发语言·游戏·unity·c#·unity3d