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的可以点击获取源码

`

相关推荐
陈言必行3 小时前
Unity 资源 之 Sweet Cakes Icon套装,110个高品质蛋糕图标分享
unity·游戏引擎
唐小墨同学4 小时前
机械拆装-基于Unity-装配功能的实现
unity·游戏引擎
向宇it4 小时前
【unity实战】使用unity的新输入系统InputSystem+有限状态机设计一个玩家状态机控制——实现玩家的待机 移动 闪避 连击 受击 死亡状态切换
开发语言·游戏·unity·游戏引擎
ZKY_244 小时前
【APK】Unity出android包,报错 Gradle build failed.See the Console for details
unity
向宇it5 小时前
【unity实战】使用Unity实现动作游戏的攻击 连击 轻重攻击和打击感
开发语言·游戏·unity·游戏引擎
沐沐森的故事8 小时前
Unity 之基于URP使用UniStorm Weather System天气系统
unity·游戏引擎·urp·unistorm·weather·通用管线·unistorm system
Unity游戏开发17 小时前
【Unity 角色控制器组件】
unity·游戏引擎
鹿野素材屋18 小时前
Unity按键表大全
unity·游戏引擎
milu_ELK19 小时前
【Unity学习笔记】A*寻路算法
笔记·学习·unity
沐沐森的故事1 天前
Unity之创建与导出PDF
unity·pdf·lucene·itextsharp