当前位置: 首页 > news >正文

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); // 加载图像数据到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的可以点击获取源码

`

相关文章:

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

最近做了一个发送消息的unity项目&#xff0c;需要访问剪切板里面的图片文字文件等&#xff0c;翻遍了网上的东西&#xff0c;看了不是需要导入System.Windows.Forms&#xff08;关键导入了unity还不好用&#xff0c;只能用在纯c#项目中&#xff09;&#xff0c;所以我看了下py…...

利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro API

谷歌在2024年4月发布了全新一代的多模态模型Gemini 1.5 Pro&#xff0c;Gemini 1.5 Pro不仅能够生成创意文本和代码&#xff0c;还能理解、总结上传的图片、视频和音频内容&#xff0c;并且支持高达100万tokens的上下文。在多个基准测试中表现优异&#xff0c;性能超越了ChatGP…...

极狐GitLab 17.0 重磅发布,100+ DevSecOps功能更新来啦~【一】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…...

python实现符文加、解密

在历史悠久的加密技术中&#xff0c;恺撒密码以其简单却有效的原理闻名。通过固定的字母位移&#xff0c;明文可以被转换成密文&#xff0c;而解密则是逆向操作。这种技术不仅适用于英文字母&#xff0c;还可以扩展到其他语言的字符体系&#xff0c;如日语的平假名或汉语的拼音…...

【解释】i.MX6ULL_IO_电气属性说明

【解释】i.MX6ULL_IO_电气属性说明 文章目录 1 Hyst1.1 迟滞&#xff08;Hysteresis&#xff09;是什么&#xff1f;1.2 GPIO的Hyst. Enable Field 参数1.3 应用场景 2 Pull / Keep Select Field2.1 PUE_0_Keeper — Keeper2.2 PUE_1_Pull — Pull2.3 选择Keeper还是Pull 3 Dr…...

02-《石莲》

石 莲 石莲&#xff08;学名&#xff1a;Sinocrassula indica A.Berger&#xff09;&#xff0c;别名因地卡&#xff0c;为二年生草本植物&#xff0c;全株无毛&#xff0c;具须根。花茎高15-60厘米&#xff0c;直立&#xff0c;常被微乳头状突起。茎生叶互生&#xff0c;宽倒披…...

MySQL之聚簇索引和非聚簇索引

1、什么是聚簇索引和非聚簇索引&#xff1f; 聚簇索引&#xff0c;通常也叫聚集索引。 非聚簇索引&#xff0c;指的是二级索引。 下面看一下它们的含义&#xff1a; 1.1、聚集索引选取规则 如果存在主键&#xff0c;主键索引就是聚集索引。如果不存在主键&#xff0c;将使…...

Web后端开发之前后端交互

http协议 http ● 超文本传输协议 &#xff08;HyperText Transfer Protocol&#xff09;服务器传输超文本到本地浏览器的传送协议 是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程。 HTTP是一个基于TCP/IP通信协议来传递数据. HTT…...

520. 检测大写字母 Easy

我们定义&#xff0c;在以下情况时&#xff0c;单词的大写用法是正确的&#xff1a; 全部字母都是大写&#xff0c;比如 "USA" 。 单词中所有字母都不是大写&#xff0c;比如 "leetcode" 。 如果单词不只含有一个字母&#xff0c;只有首字母大写&#xff0…...

vue的跳转传参

1、接收参数使用route,route包含路由信息&#xff0c;接收参数有两种方式,params和query path跳转只能使用query传参,name跳转都可以 params&#xff1a;获取来自动态路由的参数 query&#xff1a;获取来自search部分的参数 写法 path跳,query传 传参数 import { useRout…...

docker配置镜像源

1&#xff09;打开 docker配置文件 sudo nano /etc/docker/daemon.json 2&#xff09;添加 国内镜像源 {"registry-mirrors": ["https://akchsmlh.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc…...

MySQL高级-SQL优化-insert优化-批量插入-手动提交事务-主键顺序插入

文章目录 1、批量插入1.1、大批量插入数据1.2、启动Linux中的mysql服务1.3、客户端连接到mysql数据库&#xff0c;加上参数 --local-infile1.4、查询当前会话中 local_infile 系统变量的值。1.5、开启从本地文件加载数据到服务器的功能1.6、创建表 tb_user 结构1.7、上传文件到…...

认识100种电路之振荡电路

在电子电路领域&#xff0c;振荡是一项至关重要的功能。那么&#xff0c;为什么电路中需要振荡&#xff1f;其背后的原理是什么&#xff1f;让我们一同深入探究。 【为什么需要振荡电路】 简单来说&#xff0c;振荡电路的存在是为了产生周期性的信号。在众多电子设备中&#…...

SSH 无密登录配置流程

一、免密登录原理 非对称加密&#xff1a; 由于对称加密的存在弊端&#xff0c;就产生了非对称加密&#xff0c;非对称加密中有两个密钥&#xff1a;公钥和私钥。公钥由私钥产生&#xff0c;但却无法推算出私钥&#xff1b;公钥加密后的密文&#xff0c;只能通过对应的私钥来解…...

Python自动化运维 系统基础信息模块

1.系统信息的收集 系统信息的收集&#xff0c;对于服务质量的把控&#xff0c;服务的监控等来说是非常重要的组成部分&#xff0c;甚至是核心的基础支撑部分。我们可以通过大量的核心指标数据&#xff0c;结合对应的检测体系&#xff0c;快速的发现异常现象的苗头&#xff0c;进…...

如何安装和配置Monit

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 关于 Monit Monit 是一个有用的程序&#xff0c;可以自动监控和管理服务器程序&#xff0c;以确保它们不仅保持在线&#xff0c;而且文…...

【redis】redis分片集群基础知识

1、基本概念 1.1定义 分片&#xff1a;数据按照某种规则&#xff08;比如哈希&#xff09;被分割成多个片段&#xff08;或分片&#xff09;&#xff0c;每个片段被称为一个槽&#xff08;slot&#xff09;。槽是Redis分片集群中数据的基本单元。节点&#xff1a;Redis分片集…...

Python 面试【★★★★】

欢迎莅临我的博客 &#x1f49d;&#x1f49d;&#x1f49d;&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

Knife4j 2.2.X 版本 swagger彻底禁用

官方文档配置权限&#xff1a;https://doc.xiaominfo.com/v2/documentation/accessControl.html#_3-5-1-%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E5%B1%8F%E8%94%BD%E8%B5%84%E6%BA%90 通常有时候我们碰到的问题如下&#xff1a; 在开发Knife4j功能时,同很多开发者经常讨论的问…...

linux下mysql的定时备份

备份是容灾的基础&#xff0c;是指为了防止系统出现操作或系统故障导致数据丢失&#xff0c;而将全部或部分数据集合从应用主机的硬盘或阵列复制到其他的存储介质的过程为什么备份 硬件故障软件故障误操作病毒入侵保留历史记录灾难性事件 存储介质 光盘磁带硬盘磁盘阵列DAS:直接…...

跨境电商AI Agent技术拆解:从RPA到智能体,店铺自动化运营的架构与实践

当大模型“驱动”RPA&#xff0c;跨境电商运营正在从“脚本自动化”迈向“意图驱动”的数字员工时代 写在前面 跨境电商卖家每天面对多平台&#xff08;Amazon、eBay、TikTok、Temu、Shopee等&#xff09;、多店铺、多站点&#xff0c;运营工作高度重复&#xff1a;采集竞品数…...

UHP驱动器热管理:Flotherm仿真与优化实践

1. UHP高电流驱动器热设计挑战在投影仪用超高压(UHP)灯驱动器的开发中&#xff0c;热管理始终是制约产品小型化和功率提升的关键瓶颈。飞利浦工业技术中心的案例显示&#xff0c;当驱动器体积从150x73x32mm缩减到120x41x24mm时&#xff0c;功率密度从0.02mW/mm激增至0.18mW/mm—…...

用STM32F103和DHT11做个智能温湿度报警器,附ESP8266远程监控代码

STM32F103与DHT11打造智能环境监测系统&#xff1a;从本地报警到云端监控全解析 在智能家居和工业物联网快速发展的今天&#xff0c;环境监测系统已成为许多创客和开发者入门的首选项目。本文将带你用STM32F103微控制器和DHT11温湿度传感器&#xff0c;构建一个功能完善的智能…...

GraphAgent:大语言模型与图数据融合的智能体框架解析与实践

1. 项目概述&#xff1a;当大语言模型遇上图数据最近在折腾一些涉及复杂关系数据的项目&#xff0c;比如学术文献网络、社交关系分析&#xff0c;甚至是企业内部的知识库梳理。这些场景里&#xff0c;数据不只是孤立的文本或数字&#xff0c;它们之间充满了各种显式的连接&…...

3步掌握Blender 3MF插件:构建高效3D打印工作流

3步掌握Blender 3MF插件&#xff1a;构建高效3D打印工作流 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 在3D打印和数字制造领域&#xff0c;模型格式转换是连接设计与…...

Python Flask应用如何实现用户画像分析_记录用户行为与分析数据

关键在于异步解耦&#xff1a;行为日志先入内存队列或Redis&#xff0c;由独立worker批量落库&#xff1b;统一用持久visitor_id绑定用户行为&#xff0c;避免ID断链&#xff1b;标签采用宽表关联表双层结构&#xff0c;支持高效查询与灵活迭代。Flask 中怎么记录用户行为而不拖…...

微信网页版访问难题如何破解?wechat-need-web浏览器扩展的轻量级替代方案探索

微信网页版访问难题如何破解&#xff1f;wechat-need-web浏览器扩展的轻量级替代方案探索 【免费下载链接】wechat-need-web 让微信网页版可用 / Allow the use of WeChat via webpage access 项目地址: https://gitcode.com/gh_mirrors/we/wechat-need-web 你是否曾在公…...

RT-Thread Smart下基于74LV595的KSZ8081网卡复位与驱动移植实战

1. 硬件连接与复位逻辑解析 第一次拿到i.MX6ULL开发板时&#xff0c;我发现KSZ8081网卡的复位引脚竟然接在了74LV595芯片上&#xff0c;这和常见的直接连接GPIO的设计完全不同。这种设计虽然节省了GPIO资源&#xff0c;但给驱动开发带来了新挑战。 74LV595是典型的串行输入并行…...

别再只用AES了!手把手教你用Java BouncyCastle库实现SM4国密加密(附完整工具类)

国密算法实战&#xff1a;用Java BouncyCastle实现SM4加密的完整指南 在数据安全领域&#xff0c;国际通用算法长期占据主导地位&#xff0c;但随着技术自主可控需求的提升&#xff0c;国产密码算法正成为企业级应用的新选择。SM4作为我国商用密码标准体系中的重要对称加密算法…...

基于Next.js 14与Sanity构建高性能个人博客:全栈技术栈解析与实践

1. 项目概述&#xff1a;一个现代、高性能的个人博客系统 最近在折腾个人博客&#xff0c;发现了一个非常亮眼的开源项目——CaliCastle/cali.so。这不仅仅是一个博客模板&#xff0c;更是一个集成了当前前端最佳实践的完整个人网站解决方案。原作者Cali&#xff08;Calvin&am…...