Есть ли способ в word VBA найти расширение встроенного изображения (InlineShape) (jpeg, png, emf …)?

#vba #ms-word #file-extension

#vba #ms-word #расширение файла

Вопрос:

Я пытаюсь определить в документе docx расширение встроенных изображений. Возможно, этот документ open xml был создан другим пользователем с помощью Microsoft Word или OpenOffice. Изображения были встроены с помощью ленты или перетаскивания, и они могут быть InlineShape (в зависимости от времени) или Shape. Мне нужно получить доступ к расширению, потому что затем документ (не в моей юрисдикции) анализируется и преобразуется в pdf, а некоторые расширения изображения несовместимы с процессом (а именно emf из wmf).

У этих изображений может не быть имен или свойств альтернативного текста. Свойство LinkFormat также недоступно, поскольку они встроены. Просматривая ActiveDocument.Строка WordOpenXML, я могу узнать, есть ли такие изображения. Но тогда я не могу связать их с соответствующей формой в документе, чтобы определить, какое изображение будет проблематичным. Поскольку они встроены, папка media в docx zip содержит изображение, и они связаны с идентификаторами в документе через document.xml.rels, например

 <Relationship Target="media/image1.emf" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Id="rId8"/>
  

Теперь я могу найти в document.xml где используется это rId8 :

 <w:drawing>
  <wp:inline distT="0" distB="0" distL="0" distR="0" wp14:anchorId="59736095" wp14:editId="3A4D29FE">
    <wp:extent cx="1286510" cy="712470"/>
    <wp:effectExtent l="0" t="0" r="8890" b="0"/>
    <wp:docPr id="2" name="Picture 2"/>
    <wp:cNvGraphicFramePr>
      <a:graphicFrameLocks noChangeAspect="1"/>
    </wp:cNvGraphicFramePr>
    <a:graphic>
      <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
        <pic:pic>
          <pic:nvPicPr>
            <pic:cNvPr id="0" name="Picture 2"/>
            <pic:cNvPicPr>
              <a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
            </pic:cNvPicPr>
          </pic:nvPicPr>
          <pic:blipFill>
            <a:blip r:embed="rId8" cstate="print">
              <a:extLst>
                <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                  <a14:useLocalDpi val="0"/>
                </a:ext>
              </a:extLst>
            </a:blip>
            <a:srcRect/>
            <a:stretch>
              <a:fillRect/>
            </a:stretch>
          </pic:blipFill>
          <pic:spPr bwMode="auto">
          </pic:spPr>
        </pic:pic>
      </a:graphicData>
    </a:graphic>
  </wp:inline>
</w:drawing>
  

С этого момента я застрял! Что делать с любыми из этих данных?
Родительский узел чертежа — это абзац с идентификатором

 w14:paraId="78D01A35"
  

но это единственный экземпляр идентификатора в ActiveDocument.Строка WordOpenXML.

Я хотел бы иметь указатели относительно того, где я могу посмотреть. Насколько я понимаю, когда Word анализирует docx и создает объектную модель, он преобразует ссылки отношений в InlineShape с привязками в нужном месте. Но при этом почему-то теряется вся ссылка на название изображения или местоположение в zip-файле docx.

PS: Мне нужно найти решение в vba word

Комментарии:

1. В структуре ZIP-архива doc нет папки «media»?

2. Есть. Это то, что указано в xml отношения. Я думаю, я мог бы пойти и открыть носитель, чтобы иметь визуальное представление о том, какое изображение в документе неверно, но тогда это больше не было бы автоматическим. Мне нужно автоматическое решение в моем макросе word vba.

3. Я подумал, что вы могли бы использовать код, чтобы заглянуть в папку мультимедиа и посмотреть расширения…

4. Да, это в основном то, что я делаю, просматривая ActiveDocument . Строка WordOpenXML Я узнаю содержимое папки мультимедиа, не разархивируя

Ответ №1:

Вы на правильном пути. rId Это «ссылка» между расположением изображения в документе и фактическим графическим файлом.

Вся информация в document.xml это «форматирование», так что расширение файла (тип изображения) никогда не будет сохранено там, только в отношении мультимедиа.

В document.xml вот где найти rId в показываемом вами XML

   <pic:blipFill>
        <a:blip r:embed="rId8" cstate="print">
  

Что вам нужно выбрать, так это blip и затем embed . Эта информация может помочь вам http://officeopenxml.com/drwPic-ImageData.php

Вы можете попробовать использовать регулярное выражение или какой-либо синтаксический анализ строки, чтобы подобрать это. Или это можно было бы сделать с помощью MSXML и XML «синтаксического анализа». То, что будет работать, будет зависеть от того, насколько точно все эти вещи соответствуют узнаваемому шаблону, и сколько времени / усилий вам потребуется, чтобы научиться использовать объектную модель XML.

Комментарии:

1. Большое спасибо, что изучили это. Я выполняю поиск в xml с помощью функции vba InStr. Что мне не удается, так это найти место в «документе», например, выбрать изображение в объекте выбора. Моя работа заключается в том, чтобы посмотреть в xml перед изображением конкретный шаблон: [a specific markup] . И чем я могу определить изображение, сообщите пользователю, какое изображение не в хорошем формате. Из вашего ответа я понял, что вы можете embed использовать изображение. Что это значит? Как мне этого добиться? Ваша ссылка позволила мне понять, что означает a:blip строка, большое спасибо.