设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

VBA(Access或Excel)如何将剪切板的图片数据保存为BMP或JPG文件

2015-4-17 23:45| 发布者: tmtony| 查看: 6140| 评论: 3|原作者: tmtony|来自: Office中国

摘要: 在帮林岚做一个将Excel的任意单元格的内容复制转为图片,然后将图片再另存为BMP或JPG 开始是使用excel自带的方法,先复制单元格内容,然后按住shift 点击编辑 菜单,有一个 复制为图片 的菜单项。这样图片就转到剪 ...
在帮林岚做一个将Excel的任意单元格的内容复制转为图片,然后将图片再另存为BMP或JPG
开始是使用excel自带的方法,先复制单元格内容,然后按住shift 点击编辑 菜单,有一个 复制为图片 的菜单项。这样图片就转到剪切板了
再对剪切板进行编程
后来发现还有有点麻烦。
就改成直接做成一个通用函数,可对任何指定的区域操作,将指定的区域内容直接转换保存为指定的文件


  1. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long

  2. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long

  3. Private Declare Function CloseClipboard Lib "user32" () As Long

  4. Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" _
  5. (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, _
  6. IPic As IPicture) As Long

  7. '\\ 定义一个 UDT 来保存IPicture OLE接口的 GUID
  8. Private Type GUID
  9. Data1 As Long
  10. Data2 As Integer
  11. Data3 As Integer
  12. Data4(0 To 7) As Byte
  13. End Type

  14. '\\ 定义一个 UDT保存 bitmap信息
  15. Private Type uPicDesc
  16. Size As Long
  17. Type As Long
  18. hPic As Long
  19. hPal As Long
  20. End Type

  21. Private Const CF_BITMAP = 2
  22. Private Const PICTYPE_BITMAP = 1

  23. Private Sub SaveRangePic(SourceRange As Range, FilePathName As String)


  24. Dim IID_IDispatch As GUID
  25. Dim uPicinfo As uPicDesc
  26. Dim IPic As IPicture
  27. Dim hPtr As Long

  28. '\\ 复制Range到剪切板 ClipBoard
  29. SourceRange.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
  30. OpenClipboard 0
  31. hPtr = GetClipboardData(CF_BITMAP)
  32. CloseClipboard

  33. '\\ 为picture图片创建一个 GUID 接口
  34. With IID_IDispatch
  35. .Data1 = &H7BF80980
  36. .Data2 = &HBF32
  37. .Data3 = &H101A
  38. .Data4(0) = &H8B
  39. .Data4(1) = &HBB
  40. .Data4(2) = &H0
  41. .Data4(3) = &HAA
  42. .Data4(4) = &H0
  43. .Data4(5) = &H30
  44. .Data4(6) = &HC
  45. .Data4(7) = &HAB
  46. End With

  47. '\\用相关数据填充 uPicInfo
  48. With uPicinfo
  49. .Size = Len(uPicinfo) '结构体长度
  50. .Type = PICTYPE_BITMAP '图片类型
  51. .hPic = hPtr '图片句柄
  52. .hPal = 0 '\\ palette句柄 (如果 是 bitmap).
  53. End With

  54. '\\创建Range对应的 Picture对象
  55. OleCreatePictureIndirect uPicinfo, IID_IDispatch, True, IPic

  56. '\\另存 Picture 对象到文件
  57. stdole.SavePicture IPic, FilePathName

  58. End Sub
复制代码


调用方法非常的简单,方法如下:  (www.Office-cn.net)
SaveRangePic Sheet1.Range("E10:F11"), "C:\tmtony.bmp"

值得注意的几点
1.要定义好相应的API。可放在模块或本窗体中
2.如果你的Access同时引用了word和excel,因为word 和excel都有range对象,所以要显示将函数的range改为excel.range ,否则调用将失败
    或将excel的引用放在前面也可以

以前网站和论坛与剪切板相关的贴子和链接(几乎涉及到剪切板的大部分操作的源码)
1.用代码插入图片到OLE对象的2种方法
   http://www.access-cn.com/info/info3396.html
2.Access从剪切版里复制和粘贴数据
   http://www.access-cn.com/info/info2045.html
3.如何把字符串传送到系统剪贴板?
   http://www.access-cn.com/info/info2467.html
4.Access把文本框复制到剪贴板的例子
   http://www.access-cn.com/info/info1831.html
5.VBA保存剪贴板为Bmp(加PrtScrn截屏)
    http://www.access-cn.com/info/info3461.html
6.VBA保存剪贴板为JPG(加PrtScrn截屏)
   http://www.access-cn.com/info/info3460.html

网上搜索的相关资料(放在这里做个备忘,以免忘记),同时稍做了一下分类与整理,也给有同样问题的网友一个参考,希望对你们有用
1.将Excel整个截屏并另存为BMP文件 (测试是成功的)
  1. Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
  2. Enum JpMode
  3.       theScreen = 0 '全屏截图
  4.       theForm = 1 '当前焦点窗口截图
  5. End Enum


  6. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  7. Private Declare Function CloseClipboard Lib "user32" () As Long
  8. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  9. Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PicBmp, RefIID As Guid, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
  10. Private Const CF_BITMAP = 2
  11. Private Type PicBmp
  12.     Size As Long
  13.     Type As Long
  14.     hBmp As Long
  15.     hPal As Long
  16.     Reserved As Long
  17. End Type

  18. Private Type Guid
  19.     Data1 As Long
  20.     Data2 As Integer
  21.     Data3 As Integer
  22.     Data4(0 To 7) As Byte
  23. End Type
  24. Function ApiGetClipBmp() As IPicture
  25. On Error Resume Next
  26.     Dim Pic As PicBmp, IID_IDispatch As Guid
  27.     OpenClipboard 0 'OpenClipboard
  28.     With IID_IDispatch
  29.         .Data1 = &H20400
  30.         .Data4(0) = &HC0
  31.         .Data4(7) = &H46
  32.     End With

  33.     With Pic
  34.         .Size = Len(Pic)
  35.         .Type = 1
  36.         .hBmp = GetClipboardData(CF_BITMAP)
  37.     End With
  38.    
  39.     OleCreatePictureIndirect Pic, IID_IDispatch, 1, ApiGetClipBmp
  40.     'stdole.SavePicture ApiGetClipBmp, "c:\clipboard.bmp"
  41.     CloseClipboard
  42. End Function
  43. Function KeyJp(Optional ByVal TheMode As JpMode = theScreen) As IPictureDisp
  44.    '版权所有,请保留作者信息.QQ:1085992075   '如需商业用途请联系作者
  45.       Call keybd_event(vbKeySnapshot, TheMode, 0, 0) '
  46.       DoEvents
  47.       'Set KeyJp = Clipboard.GetData
  48. End Function
  49. '┗〓〓〓〓〓〓〓〓〓  KeyJp,end  〓〓〓〓〓〓〓〓〓┛
  50. Sub dd()
  51.   KeyJp (theScreen)
  52.   SavePicture ApiGetClipBmp, "c:\2.bmp"
  53. End Sub
复制代码



2.这个程序说起来也不复杂,涉及到两类API函数,一类是剪贴板函数,用于读取剪贴板中的位图句柄,另外一类是GDI+函数,用于位图到jpg文件的转换,具体代码如下:
  1. Option Explicit
  2. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  3. Private Declare Function CloseClipboard Lib "user32" () As Long
  4. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  5. Private Const CF_BITMAP = 2

  6. Private Type GUID
  7. Data1 As Long
  8. Data2 As Integer
  9. Data3 As Integer
  10. Data4(0 To 7) As Byte
  11. End Type

  12. Private Type GdiplusStartupInput
  13. GdiplusVersion As Long
  14. DebugEventCallback As Long
  15. SuppressBackgroundThread As Long
  16. SuppressExternalCodecs As Long
  17. End Type

  18. Private Type EncoderParameter
  19. GUID As GUID
  20. NumberOfValues As Long
  21. type As Long
  22. Value As Long
  23. End Type

  24. Private Type EncoderParameters
  25. Count As Long
  26. Parameter As EncoderParameter
  27. End Type

  28. Private Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, ByVal outputbuf As Long) As Long
  29. Private Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As Long
  30. Private Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As Long) As Long
  31. Private Declare Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As Long, ByVal filename As Long, clsidEncoder As GUID, encoderParams As Any) As Long
  32. Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long
  33. Private Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As Long, ByVal hPal As Long, BITMAP As Long) As Long

  34. Sub test()
  35.     Select Case CliptoJPG("c:\test.jpg")
  36.         Case 0:
  37.             MsgBox "剪贴板图片已保存"
  38.         Case 1:
  39.             MsgBox "剪贴板图片保存失败"
  40.         Case 2:
  41.             MsgBox "剪贴板中无图片"
  42.         Case 3:
  43.             MsgBox "剪贴板无法打开,可能被其他程序所占用"
  44.     End Select
  45. End Sub


  46. Private Function CliptoJPG(ByVal destfilename As String, Optional ByVal quality As Byte = 80) As Integer
  47. '*****该函数用于取出剪贴板中图片转换为jpg文件另存到指定路径****
  48. '参数说明:
  49. '     destfilename:要保存的jpg文件的完整路径,必要参数;
  50. '     quality: jpg文件的质量,0-100之间的数值,数值越大,图片质量越高
  51. '返回值:
  52. '     0-保存成功;1-保存失败;2-剪贴板中无位图数据;3-无法打开剪贴板

  53.     Dim tSI As GdiplusStartupInput
  54.     Dim lRes As Long
  55.     Dim lGDIP As Long
  56.     Dim lBitmap As Long
  57.     Dim hBmp As Long
  58.    
  59.     '尝试打开剪贴板
  60.     If OpenClipboard(0) Then
  61.         '尝试取出剪贴板中位图的句柄
  62.         hBmp = GetClipboardData(CF_BITMAP)
  63.         '如果hBmp为0,说明剪贴板中没有存放图片
  64.         If hBmp = 0 Then
  65.             CliptoJPG = 2
  66.             CloseClipboard
  67.             Exit Function
  68.         End If
  69.         CloseClipboard
  70.     Else   '如果openclipboard返回0(False),说明剪贴板被其他程序所占用
  71.         CliptoJPG = 3
  72.         Exit Function
  73.     End If
  74.    
  75.     '初始化 GDI+
  76.     tSI.GdiplusVersion = 1
  77.     lRes = GdiplusStartup(lGDIP, tSI, 0)
  78.      
  79.     If lRes = 0 Then
  80.         '从句柄创建 GDI+ 图像
  81.         lRes = GdipCreateBitmapFromHBITMAP(hBmp, 0, lBitmap)
  82.          
  83.         If lRes = 0 Then
  84.             Dim tJpgEncoder As GUID
  85.             Dim tParams As EncoderParameters
  86.             
  87.             '初始化解码器的GUID标识
  88.             CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
  89.             
  90.             '设置解码器参数
  91.             tParams.Count = 1
  92.             With tParams.Parameter ' Quality
  93.                 '得到Quality参数的GUID标识
  94.                 CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
  95.                 .NumberOfValues = 1
  96.                 .type = 4
  97.                 .Value = VarPtr(quality)
  98.             End With
  99.             
  100.             '保存图像
  101.             lRes = GdipSaveImageToFile(lBitmap, StrPtr(destfilename), tJpgEncoder, tParams)
  102.             If lRes = 0 Then
  103.                 CliptoJPG = 0  '转换成功
  104.             Else
  105.                 CliptoJPG = 1  '转换失败
  106.             End If
  107.             
  108.             '销毁GDI+图像
  109.             GdipDisposeImage lBitmap
  110.         End If
  111.          
  112.         '销毁 GDI+
  113.         GdiplusShutdown lGDIP
  114.     End If
  115. End Function
复制代码





相关阅读

发表评论

最新评论

引用 t小宝 2015-4-17 23:51
好资料!
引用 玉树TMD临风 2015-7-6 00:24
这么麻烦的。

打开的记录集某个字段怎样取剪贴板的值?

比如rst("地址")=后面怎么写?
引用 p51219 2016-7-10 00:30
好好好呵呵呵呵呵

查看全部评论(3)

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-4 07:07 , Processed in 0.078657 second(s), 24 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

返回顶部