ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] VBA生成的二维码图片如何把他放在USERFORM上

[复制链接]

TA的精华主题

TA的得分主题

发表于 2023-4-26 11:40 | 显示全部楼层 |阅读模式
QRCODE_test.zip (109.42 KB, 下载次数: 36)


我在EXCEL里用VBA生成了一个二维码图片, 但是我希望吧这个二维码图片放在USERFORM上,
我尝试用 userform1.image 去粘贴发现无法执行.
这个应该怎么改?


TA的精华主题

TA的得分主题

发表于 2023-4-26 15:10 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2023-4-26 15:14 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-26 16:30 | 显示全部楼层

多谢, loadpicture 是针对物理存在一个图片文件进行导入.
能否直接从内存里把他粘贴上去.

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-26 16:31 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2023-4-26 16:51 | 显示全部楼层
大氵寿 发表于 2023-4-26 16:31
多谢, 学习一下..但是我想把图片从剪切板放入用户窗体..

对图片数据结构进行了解,然后利用windowsAPI去绘制或许能实现
如果打算用LoadPicture方法是不支持的。还是建议保存一下,再load。

TA的精华主题

TA的得分主题

发表于 2023-4-26 17:02 | 显示全部楼层
大氵寿 发表于 2023-4-26 16:31
多谢, 学习一下..但是我想把图片从剪切板放入用户窗体..


先将剪切板内的图片 导出为图片文件
再将文件读取到image

1.png

下面是将剪切板图片 保存为文件的函数


  1. '''Sub test()
  2. '''    Select Case ClipboardToJPG("c:\test.jpg")
  3. '''        Case 0:
  4. '''            MsgBox "剪贴板图片已保存"
  5. '''        Case 1:
  6. '''            MsgBox "剪贴板图片保存失败"
  7. '''        Case 2:
  8. '''            MsgBox "剪贴板中无图片"
  9. '''        Case 3:
  10. '''            MsgBox "剪贴板无法打开,可能被其他程序所占用"
  11. '''        Case 4:
  12. '''            MsgBox "GDI+错误"
  13. '''    End Select
  14. '''End Sub

  15. Option Explicit
  16. Private Type GUID
  17.     Data1 As Long
  18.     Data2 As Integer
  19.     Data3 As Integer
  20.     Data4(0 To 7) As Byte
  21. End Type

  22. #If VBA7 And Win64 Then
  23.     Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long
  24.     Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
  25.     Private Declare PtrSafe Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  26.     Private Declare PtrSafe Function GdiplusStartup Lib "GDIPlus" (token As LongPtr, inputbuf As GdiplusStartupInput, ByVal outputbuf As LongPtr) As LongPtr
  27.     Private Declare PtrSafe Function GdiplusShutdown Lib "GDIPlus" (ByVal token As LongPtr) As LongPtr
  28.     Private Declare PtrSafe Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As LongPtr) As LongPtr
  29.     Private Declare PtrSafe Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As LongPtr, ByVal filename As LongPtr, clsidEncoder As GUID, encoderParams As Any) As LongPtr
  30.     Private Declare PtrSafe Function CLSIDFromString Lib "ole32" (ByVal str As LongPtr, id As GUID) As LongPtr
  31.     Private Declare PtrSafe Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As LongPtr, ByVal hPal As LongPtr, BITMAP As LongPtr) As LongPtr
  32.     Private Type EncoderParameter
  33.         GUID As GUID
  34.         NumberOfValues As Long
  35.         type As Long
  36.         Value As LongPtr
  37.     End Type
  38.     Private Type GdiplusStartupInput
  39.         GdiplusVersion As Long
  40.         DebugEventCallback As LongPtr
  41.         SuppressBackgroundThread As Long
  42.         SuppressExternalCodecs As Long
  43.     End Type
  44. #Else
  45.     Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  46.     Private Declare Function CloseClipboard Lib "user32" () As Long
  47.     Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  48.     Private Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, ByVal outputbuf As Long) As Long
  49.     Private Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As Long
  50.     Private Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As Long) As Long
  51.     Private Declare Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As Long, ByVal filename As Long, clsidEncoder As GUID, encoderParams As Any) As Long
  52.     Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long
  53.     Private Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As Long, ByVal hPal As Long, BITMAP As Long) As Long
  54.     Private Type EncoderParameter
  55.         GUID As GUID
  56.         NumberOfValues As Long
  57.         type As Long
  58.         Value As Long
  59.     End Type
  60.     Private Type GdiplusStartupInput
  61.         GdiplusVersion As Long
  62.         DebugEventCallback As Long
  63.         SuppressBackgroundThread As Long
  64.         SuppressExternalCodecs As Long
  65.     End Type
  66. #End If

  67. Private Const CF_BITMAP = 2
  68. Private Type EncoderParameters
  69.     Count As Long
  70.     Parameter As EncoderParameter
  71. End Type

  72. Public Function ClipboardToJPG(ByVal destfilename As String, Optional ByVal quality As Byte = 100) As Integer
  73.     Rem  该函数用于取出剪贴板中图片转换为jpg文件另存到指定路径****
  74.     Rem  参数说明:
  75.     Rem      destfilename:要保存的jpg文件的完整路径,必要参数;
  76.     Rem      quality: jpg文件的质量,0-100之间的数值,数值越大,图片质量越高
  77.     Rem      返回值:
  78.     Rem      0-保存成功;1-保存失败;2-剪贴板中无位图数据;3-无法打开剪贴板
  79.     Dim tSI As GdiplusStartupInput
  80.    
  81.     #If VBA7 Then
  82.         Dim lRes As LongPtr
  83.         Dim lGDIP As LongPtr
  84.         Dim lBitmap As LongPtr
  85.         Dim hBmp As LongPtr
  86.     #Else
  87.         Dim lRes As Long
  88.         Dim lGDIP As Long
  89.         Dim lBitmap As Long
  90.         Dim hBmp As Long
  91.     #End If
  92.    
  93.     Rem  尝试打开剪贴板
  94.     If OpenClipboard(0) Then
  95.         Rem  尝试取出剪贴板中位图的句柄
  96.         hBmp = GetClipboardData(CF_BITMAP)
  97.         Rem  如果hBmp为0,说明剪贴板中没有存放图片
  98.         If hBmp = 0 Then
  99.             ClipboardToJPG = 2
  100.             CloseClipboard
  101.             Exit Function
  102.         End If
  103.         CloseClipboard
  104.     Else   '如果openclipboard返回0(False),说明剪贴板被其他程序所占用
  105.         ClipboardToJPG = 3
  106.         Exit Function
  107.     End If
  108.     Rem  初始化 GDI+
  109.     tSI.GdiplusVersion = 1
  110.     lRes = GdiplusStartup(lGDIP, tSI, 0)
  111.     If lRes = 0 Then
  112.         Rem  从句柄创建 GDI+ 图像
  113.         lRes = GdipCreateBitmapFromHBITMAP(hBmp, 0, lBitmap)
  114.         If lRes = 0 Then
  115.             Dim tJpgEncoder As GUID
  116.             Dim tParams As EncoderParameters
  117.             Rem  初始化解码器的GUID标识
  118.             CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
  119.             Rem  设置解码器参数
  120.             tParams.Count = 1
  121.             With tParams.Parameter ' Quality
  122.                 Rem  得到Quality参数的GUID标识
  123.                 CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
  124.                 .NumberOfValues = 1
  125.                 .type = 4
  126.                 .Value = VarPtr(quality)
  127.             End With
  128.             Rem  保存图像
  129.             lRes = GdipSaveImageToFile(lBitmap, StrPtr(destfilename), tJpgEncoder, tParams)
  130.             If lRes = 0 Then
  131.                 ClipboardToJPG = 0  '转换成功
  132.             Else
  133.                 ClipboardToJPG = 1  '转换失败
  134.             End If
  135.             Rem  销毁GDI+图像
  136.             GdipDisposeImage lBitmap
  137.         End If
  138.         Rem  销毁 GDI+
  139.         GdiplusShutdown lGDIP
  140.     Else
  141.         ClipboardToJPG = 4
  142.     End If
  143. End Function

复制代码


TA的精华主题

TA的得分主题

发表于 2023-4-26 17:22 | 显示全部楼层
Public Function ClipboardToJPG(ByVal destfilename As String, Optional ByVal quality As Byte = 80) As Integer
    Rem  该函数用于取出剪贴板中图片转换为jpg文件另存到指定路径****
    Rem  参数说明:
    Rem      destfilename:  要保存的jpg文件的完整路径,必要参数;
    Rem      quality:            jpg文件的质量,0-100之间的数值,数值越大,图片质量越高
    Rem  返回值:  0-保存成功;1-保存失败;2-剪贴板中无位图数据;3-无法打开剪贴板
    Dim tSI As GdiplusStartupInput
   
    #If VBA7 Then
        Dim lRes As LongPtr
        Dim lGDIP As LongPtr
        Dim lBitmap As LongPtr
        Dim hBmp As LongPtr
    #Else
        Dim lRes As Long
        Dim lGDIP As Long
        Dim lBitmap As Long
        Dim hBmp As Long
    #End If
   
    Rem  尝试打开剪贴板
    If OpenClipboard(0) Then
        Rem  尝试取出剪贴板中位图的句柄
        hBmp = GetClipboardData(CF_BITMAP)
        Rem  如果hBmp为0,说明剪贴板中没有存放图片
        If hBmp = 0 Then
            ClipboardToJPG = 2
            CloseClipboard
            Exit Function
        End If
        CloseClipboard
    Else   '如果openclipboard返回0(False),说明剪贴板被其他程序所占用
        ClipboardToJPG = 3
        Exit Function
    End If
    Rem  初始化 GDI+
    tSI.GdiplusVersion = 1
    lRes = GdiplusStartup(lGDIP, tSI, 0)
    If lRes = 0 Then
        Rem  从句柄创建 GDI+ 图像
        lRes = GdipCreateBitmapFromHBITMAP(hBmp, 0, lBitmap)
        If lRes = 0 Then
            Dim tJpgEncoder As GUID
            Dim tParams As EncoderParameters
            Rem  初始化解码器的GUID标识
            CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
            Rem  设置解码器参数
            tParams.Count = 1
            With tParams.Parameter ' Quality
                Rem  得到Quality参数的GUID标识
                CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
                .NumberOfValues = 1
                .type = 4
                .Value = VarPtr(quality)
            End With
            Rem  保存图像
            lRes = GdipSaveImageToFile(lBitmap, StrPtr(destfilename), tJpgEncoder, tParams)
            If lRes = 0 Then
                ClipboardToJPG = 0  '转换成功
            Else
                ClipboardToJPG = 1  '转换失败
            End If
            Rem  销毁GDI+图像
            GdipDisposeImage lBitmap
        End If
        Rem  销毁 GDI+
        GdiplusShutdown lGDIP
    Else
        ClipboardToJPG = 4
    End If
End Function


https://club.excelhome.net/thread-1535960-3-1.html

TA的精华主题

TA的得分主题

发表于 2023-4-26 20:32 | 显示全部楼层



其实这是非常简单的问题。把二维码并转为StdPicture对象即可使用,不用保存为文件。

https://club.excelhome.net/thread-1577992-1-1.html

2023-04-26_203001.png

程序文件和示例代码.zip (731.18 KB, 下载次数: 40)

TA的精华主题

TA的得分主题

发表于 2023-4-27 10:49 | 显示全部楼层
ivccav 发表于 2023-4-26 20:32
其实这是非常简单的问题。把二维码并转为StdPicture对象即可使用,不用保存为文件。

https://club ...

代码内添加Logo的函数不错
不知道能否改进一下:
  不管Logo图片原来多大
  在函数中直接缩小到二维码的几分之一
  或按比例缩小后放上去

  1. Rem 二维码添加logo
  2. Public Sub QRCodeAddLogo(ByVal QRPath As String, ByVal LogoPath As String, ByVal PathOut As String, Optional ByVal IntZoom As Integer = 3)
  3.     Rem QRPath      原始图片,二维码图片
  4.     Rem LogoPath   中心Logo图片文件
  5.     Rem PathOut     输出图片名称
  6.     Rem IntZoom     中心Logo占原始图片的比例
  7.    
  8.     Dim Logo, IMG As Object
  9.     Dim IP, FSO As Object
  10.    
  11.     Set IMG = CreateObject("WIA.ImageFile")
  12.     Set Logo = CreateObject("WIA.ImageFile")
  13.     Set IP = CreateObject("WIA.ImageProcess")
  14.    
  15.     IMG.LoadFile QRPath
  16.     Logo.LoadFile LogoPath
  17.     Rem 怎样将Logo这个图片进行缩小,以适应二维码图片的大小
  18.     '''    IP.Filters(1).Properties("Left") = IMG.Width /  IntZoom
  19.     '''    IP.Filters(1).Properties("Top") = IMG.Height /  IntZoom
  20.    
  21.     IP.Filters.Add IP.FilterInfos("Stamp").FilterID
  22.     Set IP.Filters(1).Properties("ImageFile") = Logo
  23.     IP.Filters(1).Properties("Left") = (IMG.Width - Logo.Width) / 2
  24.     IP.Filters(1).Properties("Top") = (IMG.Height - Logo.Height) / 2
  25.     Set IMG = IP.Apply(IMG)
  26.     Set FSO = CreateObject("Scripting.FileSystemObject")
  27.     If FSO.FileExists(PathOut) = True Then
  28.         Kill PathOut  '//删除文件
  29.     End If
  30.    
  31.     IMG.SaveFile PathOut
  32. End Sub
复制代码


评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-17 05:24 , Processed in 0.054807 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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