Introduction
This article contains information on how to update an image placed in an Image placeholder in a Word document and maintain the size of the new image.
Background
Let’s say you have a Word document where you would like to update an image in an image placeholder and you want to maintain the size of the new updated image.
Using the Code
Adding Image Placeholder in a Word Document
- Start Microsoft Word 2007 (or later)
- Navigate to the ‘Developer’ tab
- Click on the “Picture Content Control” icon in the “Controls” group-box. This will add an Image placeholder into the Word document.
- Select the Image placeholder by clicking it, if it is not already selected
- Click on the “Properties” button in the “Controls” group-box. This will bring up the Content control properties.
- Give the content control a title and a tagname
- Click on the icon inside the placeholder to add an image to the placeholder
- Save the document and close it
Implementation Details
To update an image to the Word document and then resize the image content control, you will need to:
- Find the Image tag node
- Find the relationship id of the image node
- Loop through the document to find all the DRAWING elements
- Loop through each of the DRAWING elements to find the one containing the BLIP for image you want to update
- Set the
cx
and cy
parameters in the EXTENT
element to the new size (Note the size is in EMU
so you will need to convert pixels to EMU
. 1 pixel = 9525 EMU) - Set the
cx
and cy
parameters in the EXTENTS
element to the new size (Note the size is in EMU
so you will need to convert pixels to EMU
. 1 pixel = 9525 EMU) - Save the document
Decoding the Word Document File
One thing I have learned since I started developing applications using Open XML is using the document deflector tool (OpenXmlSdkTool.exe). I cannot emphasize enough how helpful it is. Once you understand the usage of this tool, you will be able to work around any issues you are having with OpenXml.
In this example, we are looking at retrieving the image placeholder id. If you look in the deflector tool, open the
test.docx file and then navigate to
w:document
,
w:body
,
w:sdt
and click on the reflect button. This will then show you the XML + the code that generates the XML content. For now, forget about the code and just look at the XML code.
The image placeholder is placed under a SdtBlock
and the tag name can be found in the w:tag
. A document may have several sdtBlocks
, but because I found the image placeholder name I was looking for, I now know that I am looking at the correct sdtBlock
.
The image itself will be located in a Blip so loop through all the Blips in the sdtblock
. When you have located the correct Blip, look at the embed
parameter as this will contain the image relationship id – the identified for the image. Once you have the correct blip, you can extract its EXTENTS
which contains the size of the image in EMU
. The image placeholder size itself can be found under the EXTENT
element.
It is also very easy to identify which directive each of the different objects are found in. E.g
w:p
is a wordprocessing directive (
DocumentFormat.OpenXml.Wordprocessing
), a
w:drawing
is located in the drawing directive (
DocumentFormat.OpenXml.Drawing
), etc.
<w:sdt xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:sdtPr>
<w:alias w:val="Some Title" />
<w:tag w:val="ImagePlaceholder1" />
<w:id w:val="19550034" />
<w:picture />
</w:sdtPr>
<w:sdtContent>
<w:p w:rsidR="004E3043" w:rsidRDefault="006B65E0">
<w:r>
<w:rPr>
<w:noProof />
</w:rPr>
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing">
<wp:extent cx="6226969" cy="4981575" />
<wp:effectExtent l="19050" t="0" r="2381" b="0" />
<wp:docPr id="2" name="Picture 1" descr="test.jpg" />
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
noChangeAspect="1" />
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="test.jpg" />
<pic:cNvPicPr />
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId4" cstate="print"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" />
<a:stretch>
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:off x="0" y="0" />
<a:ext cx="6226969" cy="4981575" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:r>
</w:p>
</w:sdtContent>
Points of Interest
Again, using the Deflector tool has really helped me a lot in understanding how the OpenXML SDK works. It may look overwhelming to begin with, but it is worth looking into. Please feel free to comment on this article for improvements and criticism. When I was Googling on how to insert pictures in a Image placeholder, I found a number of articles using direct XML to find the place to update. I figured there must be a simpler way just by using the OpenXML itself, and to my relief, there was.
History
- April 27, 2011 - Application created and posted