简体   繁体   English

将InlineShape图片保存到Word中的文件 VBA

[英]Save InlineShape picture to file in Word VBA

I am trying to extract a picture from a Word document and save it in a file, using vba.我正在尝试使用 vba 从 Word 文档中提取图片并将其保存在文件中。
I don't really care about the output format, as long as it is readable.我不太关心 output 格式,只要它是可读的即可。

The picture is in line with text and is therefore an InlineShape in vba.图片与文字对齐,因此是vba中的一个InlineShape

I have tried something using the ActiveX Data Object Library (ADODB) , see code below.我已经尝试使用ActiveX Data Object Library (ADODB)进行一些操作,请参阅下面的代码。

Code代码

Dim oInlineShape As InlineShape, _
ImageStream

Set oInlineShape = ActiveDocument.InlineShapes(1)

Set ImageStream = CreateObject("ADODB.Stream")
With ImageStream
    .Type = 1
    .Open
    .Write oInlineShape.Range.EnhMetaFileBits
    .savetofile ActiveDocument.Path & "\image.bmp"
    .Close
End With
Set ImageStream = Nothing

There is no need to include the reference to the "ActiveX Data Object Library".无需包含对“ActiveX 数据 Object 库”的引用。
I have not specified ImageStream 's type to avoid having to do so.我没有指定ImageStream的类型以避免必须这样做。

Result结果

I cannot read the image.bmp file using the Windows Photos App, but I can insert it back into the Word document or convert the file to a jpg (I used ImageMagick but I don't think it matters).我无法使用 Windows 照片应用程序读取image.bmp文件,但我可以将其重新插入到 Word 文档中或将文件转换为 jpg(我使用 ImageMagick,但我认为这无关紧要)。

Original原版的 Result结果
https://i.stack.imgur.com/TCSok.jpg https://i.stack.imgur.com/QInGc.jpg
  • The result image has weird white borders.结果图像有奇怪的白色边框。 I don't know where they are coming from.我不知道他们来自哪里。
    I tried to understand by adding oInlineShape.Select in my code, only the image is selected...我试图通过在我的代码中添加oInlineShape.Select来理解,只选择了图像......
  • Its quality is very poor compared to the original image (this may not be visible in the uploaded pictures).与原始图像相比,它的质量很差(这在上传的图片中可能看不到)。
    I believe this is because I resized the image in Word.我相信这是因为我在 Word 中调整了图像的大小。

Other possible method其他可能的方法

I read in old forum threads that the vba code can call functions from the Windows API and therefore can paste the clipboard contents to a file.我在旧论坛帖子中读到 vba 代码可以调用 Windows API 中的函数,因此可以将剪贴板内容粘贴到文件中。

I know how to put a Shape or InlineShape in the Word clipboard.我知道如何将 Shape 或 InlineShape 放入 Word 剪贴板。 However, I do not know how to connect to the Windows API using vba and what function from it to use.但是,我不知道如何使用 vba 连接到 Windows API 以及从中使用什么 function。

Many many thanks!!非常感谢!!

I looked for 20 years but never found answer, until discovering WordXML.我找了 20 年但从未找到答案,直到发现 WordXML。

You can test by calling: saveImage Selection.InlineShapes(1), "C:\tmp\test.png" Make sure there is a "tmp" directory on the C drive.您可以通过调用:saveImage Selection.InlineShapes(1), "C:\tmp\test.png" 来测试确保C驱动器上有一个"tmp"目录。

Private Sub saveImage(shp As InlineShape, path As String)

    Dim s As String
    Dim i As Long
    Dim j As Long
    
    Dim r As Range
    
    Set r = shp.Range.Duplicate
    r.start = r.start - 1
    r.End = r.End + 1
    
    ''shp.range.WordOpenXML does not always contain the binary data
    ''s = shp.Range.WordOpenXML
    
    s = r.WordOpenXML
    
    i = InStr(s, "<pkg:binaryData>") + 16
    
    If i = 16 Then
        MsgBox "No binary data found"
        Exit Sub
    End If
    
    j = InStr(i, s, "</pkg:binaryData>")
    
    s = Mid$(s, i, j - i)
    
    
    Dim DecodeBase64() As Byte
    Dim objXML As Object 'MSXML2.DOMDocument
    Dim objNode As Object 'MSXML2.IXMLDOMElement

    Set objXML = CreateObject("MSXML2.DOMDocument")

    'create node with type of base 64 and decode
    Set objNode = objXML.createElement("b64")
    objNode.DataType = "bin.base64"
    objNode.Text = s
    DecodeBase64 = objNode.nodeTypedValue

    Set objNode = Nothing
    Set objXML = Nothing

    Open path For Binary As #1
       Put #1, 1, DecodeBase64
    Close #1

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM