最近做了一個發送消息的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); // 加載圖像數據到Texture2Dreturn 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的可以點擊獲取源碼
`