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

`

相关推荐
努力长头发的程序猿32 分钟前
Unity2D当中的A*寻路算法
算法·unity·c#
RReality12 小时前
【Unity Shader URP】Matcap 材质捕捉实战教程
java·ui·unity·游戏引擎·图形渲染·材质
魔士于安12 小时前
unity urp材质球大全
游戏·unity·游戏引擎·材质·贴图·模型
南無忘码至尊15 小时前
Unity学习90天 - 第 6 天 -学习物理 Material + 重力与阻力并实现弹跳球和冰面滑动效果
学习·unity·游戏引擎
mxwin17 小时前
Unity 单通道立体渲染(Single Pass Instanced)对 Shader 顶点布局的特殊要求
unity·游戏引擎·shader
魔士于安20 小时前
unity 低多边形 无人小村 木质建筑 晾衣架 盆子手推车,桌子椅子,罐子,水井
游戏·unity·游戏引擎·贴图·模型
RReality20 小时前
【Unity Shader URP】简易卡通着色(Simple Toon)实战教程
ui·unity·游戏引擎·图形渲染·材质
魔士于安20 小时前
unity 骷髅人 连招 武器 刀光 扭曲空气
游戏·unity·游戏引擎·贴图·模型
洛阳吕工1 天前
从 micro-ROS 到 px4_ros2:ROS2 无人机集成开发实战指南
游戏引擎·无人机·cocos2d
风酥糖1 天前
Godot游戏练习01-第29节-游戏导出
游戏·游戏引擎·godot