Export selection of word document as an image file(2)

来源:互联网 发布:ipad pro草图软件 编辑:程序博客网 时间:2024/04/28 03:43
  1. Option Explicit
  2. Private Declare Function EmptyClipboard Lib "user32" () As Long
  3. Private Declare Function OpenClipboard Lib "user32" _
  4.         (ByVal hwnd As Long) As Long
  5. Private Declare Function CloseClipboard Lib "user32" () As Long
  6. Private Declare Function GetClipboardData Lib "user32" _
  7.         (ByVal wFormat As Long) As Long
  8. Private Declare Function GetEnhMetaFileBits Lib "gdi32" _
  9.         (ByVal hEMF As Long, ByVal cbBuffer As Long, lpbBuffer As Byte) As Long
  10. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
  11.         (pDest As Any, pSource As Any, ByVal cbLength As Long)
  12. Private Const CF_ENHMETAFILE = 14
  13. Private emf() As Byte, imgData() As Byte
  14. Private Type EmfRecord        ' private emf-type
  15.     id As Long
  16.     len As Long
  17. End Type
  18. Private Type GDI_Comment        ' private GDI type
  19.     len As Long
  20. Type As Long
  21.     data As Long
  22. End Type
  23. Function ExportEMFPlusImageData(pBMI As Long, pDIB As Long) As Boolean
  24. ' Extract EMF-Stream from GDI+ (EMF+) Image-Data
  25.     Dim pEMF As Long, lEmf As Long, n As Long, state As Long, pNext As Long
  26.     Dim recEMF As EmfRecord, recEMFplus As GDI_Comment, pImgData As Long
  27.     Dim nextblock As Boolean, pCmd As Long, imgtype As Long, toff As Long
  28.     Dim WMFhdr As Long, WMFhsz As Integer, misalign As Boolean, big As Boolean
  29.     Dim dib As Boolean, dibits As Long, bmi As Long, imgend As Boolean
  30.     On Error Resume Next
  31.     n = UBound(emf)
  32.     If n < 7 Or Err <> 0 Then Exit Function
  33.     Do
  34.         CopyMemory recEMF, emf(pEMF), 8
  35.         'Debug.Print Hex$(pEMF), Hex$(recEMF.id), Hex$(recEMF.len)
  36.         Select Case state
  37.             Case 0:        ' header
  38.                 If recEMF.id <> 1 Or recEMF.len = 0 Then Exit Function        ' wrong header
  39.                 state = 1
  40.             Case 1:        ' wait for GDI_COMMENT Begin Group
  41.                 If recEMF.id = 70 And recEMF.len > 23 Then
  42.                     CopyMemory recEMFplus, emf(pEMF + 8), 12
  43.                     If recEMFplus.Type = &H43494447 And recEMFplus.data = 2 Then        ' GDIC
  44.                         state = 2
  45.                     End If
  46.                 End If
  47.             Case 2:        ' wait for GDI_COMMENT EMF+ (GDI+) records
  48.                 If recEMF.id = 70 And recEMF.len >= 20 Then
  49.                     CopyMemory recEMFplus, emf(pEMF + 8), 12
  50.                     'Debug.Print "+", Hex$(recEMFplus.type), Hex$(recEMFplus.data)
  51.                     If (recEMFplus.Type = &H2B464D45) And (Not imgend) Then        ' GDI+ record
  52.                         pNext = pEMF + 16
  53.                         pCmd = recEMFplus.data
  54.                         Do While (pCmd And &HFFFF&) <> &H4008        ' wait for cmd Image
  55.                             CopyMemory n, emf(pNext + 4), 4        ' len of command
  56.                             pNext = pNext + n
  57.                             If pNext >= pEMF + recEMF.len Then Exit Do
  58.                             CopyMemory pCmd, emf(pNext), 4        ' next command
  59.                         Loop
  60.                         If (pCmd And &HFFFFFFF) = &H5004008 Then        ' cmd Image + Flags
  61.                             big = (pCmd And &H80000000) = 
  62.                             toff = IIf(big, pNext + 20, pNext + 16)
  63.                             If Not (big And nextblock) Then
  64.                                 CopyMemory imgtype, emf(toff), 4
  65.                                 If imgtype = 1 Then        ' bitmap
  66.                                     ReDim imgData(recEMF.len - toff - 24 + pEMF - 1)
  67.                                     CopyMemory imgData(0), emf(toff + 24), recEMF.len - toff - 24 + pEMF
  68.                                 ElseIf imgtype = 2 Then        ' metafile
  69.                                     ReDim imgData(recEMF.len - toff - 12 + pEMF - 1): misalign = False
  70.                                     CopyMemory WMFhdr, emf(toff + 12), 4
  71.                                     CopyMemory WMFhsz, emf(toff + 12 + 22 + 2), 2
  72.                                     If WMFhdr = &H9AC6CDD7 Then        ' WMF APM Header?
  73.                                         misalign = WMFhsz <> 9        ' check Std WMF hdr misaling
  74.                                     End If
  75.                                     If misalign Then        ' correct GDI+ misalign-bug
  76.                                         CopyMemory imgData(0), emf(toff + 12), 22        ' APM header
  77.                                         CopyMemory imgData(22), emf(toff + 12 + 22 + 2), recEMF.len - toff - 12 + pEMF - 22 - 2
  78.                                         ReDim Preserve imgData(UBound(imgData) - 2)
  79.                                     Else
  80.                                         CopyMemory imgData(0), emf(toff + 12), recEMF.len - toff - 12 + pEMF
  81.                                     End If
  82.                                 Else
  83.                                     Exit Do        ' unknown type
  84.                                 End If        ' imgtype
  85.                                 If big Then nextblock = True Else imgend = True
  86.                             Else
  87.                                 n = UBound(imgData)
  88.                                 ReDim Preserve imgData(n + recEMF.len - &H20)
  89.                                 CopyMemory imgData(n + 1), emf(pEMF + &H20), recEMF.len - 
  90.                             End If        ' not (big and next)
  91.                         End If        ' cmd image
  92.                     ElseIf recEMFplus.Type = &H43494447 And recEMFplus.data = 3 Then        ' GDIC end
  93.                         Exit Do        ' EMF+ group end
  94.                     End If
  95.                 ElseIf recEMF.id = 81 And recEMF.len >= 88 And (Not dib) Then        ' EMR_StrechDibits
  96.                     dib = True
  97.                     CopyMemory n, emf(pEMF + 48), 4        ' BMIoffset (0x50)
  98.                     bmi = pEMF + n        ' BIHdr
  99.                     CopyMemory n, emf(pEMF + 56), 4        '
  100.                     dibits = pEMF + n        ' DIBits
  101.                 End If
  102.         End Select
  103.         pEMF = pEMF + recEMF.len
  104.     Loop Until pEMF > UBound(emf)
  105.     n = 0: n = UBound(imgData)
  106.     If n = 0 Then        ' if image not found, copy  metafile bits
  107.         ReDim imgData(UBound(emf)): CopyMemory imgData(0), emf(0), UBound(emf) + 1
  108.     Else: pDIB = dibits: pBMI = bmi
  109.     End If
  110.     ExportEMFPlusImageData = True
  111. End Function
  112. Sub ExportSelectionAsPicture()
  113.     If Selection Is Nothing Then        'Nothing was selected
  114.         MsgBox "Please select something to export!"
  115.         Exit Sub
  116.     End If
  117.     Dim pBMI As Long, pDIB As Long, ext As String, picType As Integer, s As String, Filename As String
  118.     Filename = InputBox("Please input the filepath and filename you want to save as""Warning""C:/mypic")
  119.     On Error Resume Next
  120.     Erase imgData: Erase emf
  121.     'Get image
  122.     ' ---------------------
  123.     Dim hEMF As Long, n As Long
  124.     If Val(Application.Version) >= 11 Then
  125.         If OpenClipboard(0&) Then
  126.             EmptyClipboard
  127.             CloseClipboard
  128.         End If
  129.         emf = Selection.EnhMetaFileBits
  130.         DoEvents
  131.     Else
  132.         'Office <=10
  133.         Selection.CopyAsPicture
  134.         If OpenClipboard(0&) Then
  135.             hEMF = GetClipboardData(CF_ENHMETAFILE)
  136.             CloseClipboard
  137.         End If
  138.         If hEMF Then
  139.             n = GetEnhMetaFileBits(hEMF, 0, ByVal 0&)
  140.             If n Then
  141.                 ReDim emf(n - 1)
  142.                 GetEnhMetaFileBits hEMF, n, emf(0)
  143.             End If
  144.         End If
  145.     End If
  146.     '-------------------------
  147.     If ExportEMFPlusImageData(pBMI, pDIB) Then
  148.         CopyMemory picType, imgData(0), 2
  149.         Select Case picType
  150.             Case &HD8FF: ext = "jpg"
  151.             Case &H4947: ext = "gif"
  152.             Case &H5089: ext = "png"
  153.             Case &H1: ext = "emf"
  154.             Case &HCDD7: ext = "wmf"
  155.             Case &H4D42: ext = "bmp"
  156.             Case &H4949: ext = "tif"
  157.             Case &H50A: ext = "pcx"
  158.             Case &H100: ext = "tga"
  159.             Case &HD0C5: ext = "eps"
  160.             Case &H2100: ext = "cgm"
  161.             Case Else: ext = "bmp"
  162.         End Select
  163.         s = Filename & "." & ext
  164.         If Len(Dir(s)) Then Kill s
  165.         Open s For Binary Access Write As #1
  166.         Put #1, 1, imgData
  167.         Close #1
  168.         MsgBox "The selection has been Exported as """ & s & """!"
  169.     Else
  170.         MsgBox "Can't Export the Selection As picture format!"
  171.     End If
  172. End Sub
原创粉丝点击