ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 377|回复: 5

[求助] 可否用VBA实现Base64 图片复制到粘贴板

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-4-9 23:51 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助


网上一段代码,将Base64图片复制到粘贴板:
  1. function b64toBlob(b64Data, contentType = null, sliceSize = null) {
  2.   contentType = contentType || 'image/png'
  3.   sliceSize = sliceSize || 512
  4.   let byteCharacters = atob(b64Data)
  5.   let byteArrays = []
  6.   for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
  7.     let slice = byteCharacters.slice(offset, offset + sliceSize)
  8.     let byteNumbers = new Array(slice.length);
  9.     for (let i = 0; i < slice.length; i++) {
  10.       byteNumbers[i] = slice.charCodeAt(i)
  11.     }
  12.     var byteArray = new Uint8Array(byteNumbers)
  13.     byteArrays.push(byteArray)
  14.   }
  15.   return new Blob(byteArrays, {type: contentType})
  16. }
复制代码
  1. function clip(b64Data) {
  2.   const item = new clipboard.ClipboardItem({
  3.     "image/png": this.b64toBlob(b64Data.replace('data:image/jpg;base64,', ''), 'image/png', 512)
  4.   });
  5. }
复制代码
请教下,可否用VBA实现,执行粘贴即为图片



TA的精华主题

TA的得分主题

发表于 2024-4-10 08:43 | 显示全部楼层
ChatGPT的回答:
  1. 要实现这个功能,我们需要使用VBA与Windows API来实现将Base64编码的图片转换为用户可以通过粘贴操作插入到目标应用中的图片。以下是实现此功能的步骤:

  2. 转换Base64为图像并保存
  3. 首先,我们需要将Base64编码的字符串转换为图像,并且保存为一个临时文件。对于这个操作,我们可以使用ADODB.Stream和GDI+ API。

  4. 使用Windows API实现复制粘贴
  5. 然后,我们将使用Windows API来进行复制到剪贴板的操作。涉及到的API函数包括OpenClipboard, EmptyClipboard, SetClipboardData, 和 CloseClipboard。

  6. 实现步骤
  7. 转换Base64字符串为图片文件

  8. 使用VBA的ADODB.Stream对象解码Base64字符串并保存为图片文件(例如,临时的JPEG文件)。

  9. 复制图片到剪贴板

  10. 使用Windows API操作,将图片文件复制到剪贴板上。

  11. 这是一个大概的例子来说明这些步骤:

  12. vb
  13. Option Explicit

  14. Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As Long
  15. Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
  16. Private Declare PtrSafe Function SetClipboardData Lib "user32" (ByVal uFormat As Long, ByVal hMem As LongPtr) As LongPtr
  17. Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
  18. Private Declare PtrSafe Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInstance As LongPtr, ByVal lpFileName As String, ByVal uType As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal fuLoad As Long) As LongPtr
  19. Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" (ByVal uFlags As Long, ByVal dwBytes As LongPtr) As LongPtr
  20. Private Declare PtrSafe Function GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
  21. Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As Long
  22. Private Declare PtrSafe Function lstrcpy Lib "kernel32" (ByVal lpString1 As Any, ByVal lpString2 As Any) As LongPtr

  23. Private Const CF_BITMAP = 2
  24. Private Const IMAGE_BITMAP = 0
  25. Private Const LR_LOADFROMFILE = &H10
  26. Private Const GMEM_MOVEABLE = &H2

  27. Sub Base64ToClipboard(Base64String As String)
  28.     Dim bytes() As Byte
  29.     Dim ImagePath As String
  30.     Dim hBitmap As LongPtr

  31.     ' 将Base64字符串转换为字节数组
  32.     bytes = DecodeBase64(Base64String)
  33.    
  34.     ' 将字节数组写入临时文件
  35.     ImagePath = SaveBytesToTempImageFile(bytes)

  36.     ' 使用API加载该图片为位图
  37.     hBitmap = LoadImage(0, ImagePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
  38.    
  39.     If hBitmap <> 0 Then
  40.         If OpenClipboard(0&) Then
  41.             Call EmptyClipboard()
  42.             ' 复制到剪贴板
  43.             Call SetClipboardData(CF_BITMAP, hBitmap)
  44.             Call CloseClipboard()
  45.         End If
  46.     End If
  47.    
  48.     ' 清理:删除临时文件
  49.     Kill ImagePath
  50. End Sub

复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-10 12:44 | 显示全部楼层

感谢版主关注,先把Base64字符串生成图片文件,再将图片导入、复制到粘贴板是可以的,
只是感觉明显走一弯路,网上看到多种语言,都能实现一步到位:
在内存中就将Base64字符串转为粘贴板中的图片格式,按Ctrl+V 就直接粘贴为图片了,
只想用VBA能否实现这一功能

TA的精华主题

TA的得分主题

发表于 2024-4-10 17:24 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
aman1516 发表于 2024-4-10 12:44
感谢版主关注,先把Base64字符串生成图片文件,再将图片导入、复制到粘贴板是可以的,
只是感觉明显走一 ...

就是 5楼 跟 8楼的 结合
https://club.excelhome.net/thread-1602346-1-1.html
2.png

TA的精华主题

TA的得分主题

发表于 2024-4-10 22:07 | 显示全部楼层
很简单:第一步,将BASE64字符串转换成Byte数组;第二步:将Byte数组转换成Stream;第三步:使用gdi+函数从Stream加载图片;第四步:使用Gdi+将加载到的图片Image转化成BitMAP格式;第五步:将BitMPA写入写字板;后面再加上一些释放函数,从后往前将BitMAP、Imag、Stream、Byte数组依次释放以防内存泄露

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-10 23:36 | 显示全部楼层
perfect131 发表于 2024-4-10 17:24
就是 5楼 跟 8楼的 结合
https://club.excelhome.net/thread-1602346-1-1.html

原来贴子数组形式不一样,基础不牢,地动山摇,“依葫芦画瓢”弄了两天,怎么也转不过来才开新贴求助,
还老师利害,实在无言言感激!
再次做个代码搬运工,终于弄好了:


微信截图_20240410233535.png
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-9-28 02:14 , Processed in 0.045760 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表