最近做了一个发送消息的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的可以点击获取源码
`