Reputation: 3954
I am attempting to iterate through the images in a PowerPoint presentation using OpenXML.
I have worked out how to do that.
I am now attempting to get the Images Alt-Text Title....
Here is my code:
List<ImagePart> imageParts = new List<ImagePart>();
part.GetPartsOfType<ImagePart>(imageParts);
foreach (ImagePart imagePart in imageParts)
{
if (imagePart != null)
{
// Get the Relationship Id
string oldRelID = part.GetIdOfPart(imagePart);
// Get the Alt-Text Tile relating to this image
}
}
Any OpenXML experts out there that could give me some pointers?
Thanks
UPDATE:
I have tried iterating through the XML but when there are multiple images on the slide I am getting the incorrect value for title for the relating image.
I think I need to be able to use the ImagePart Id to then find the corresponding title
The code below gets the titles out of order...
foreach (ImagePart imagePart in imageParts)
{
string mapReference = "";
XmlNode thisNode = pictureNodeList[imageCounter];
foreach (XmlNode xmlnode in thisNode)
{
foreach (XmlNode xmlchildnode in xmlnode)
{
foreach (XmlAttribute att in xmlchildnode.Attributes)
{
if (att.Name == "title")
{
mapReference = att.Value;
imageCounter += 1;
}
}
}
}
}
Upvotes: 6
Views: 2831
Reputation: 12815
You're 90% of the way there.
You need to find the Blip
element whose Embed
property matches the Id of the ImagePart
you have. The Blip
is contained within a BlipFill
which in turn is contained within a Picture
element. The Picture
(pic
in the XML) element has a NonVisualPictureDrawingProperties
element (nvPicPr
) which in turn has a NonVisualDrawingProperties
element (cNvPr
) and it's in there where you'll find the title. For example your XML could look like this:
<p:pic>
<p:nvPicPr>
<p:cNvPr id="4" name="Picture 3" descr="My Description" title="My Title" />
<p:cNvPicPr>
<a:picLocks noChangeAspect="1" />
</p:cNvPicPr>
<p:nvPr />
</p:nvPicPr>
<p:blipFill>
<a:blip r:embed="rId2" cstate="print">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0" />
</a:ext>
</a:extLst>
</a:blip>
<a:stretch>
<a:fillRect />
</a:stretch>
</p:blipFill>
<p:spPr>
<a:xfrm>
<a:off x="7260298" y="5445224" />
<a:ext cx="1883701" cy="1412776" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</p:spPr>
</p:pic>
The following code will output the Title
property of each image. Note that as you have a strongly typed Picture
object you can get to the other properties easily too (such as Description
for example).
using (PresentationDocument doc =
PresentationDocument.Open(filename, false))
{
//get the first slide
SlidePart part = doc.PresentationPart.SlideParts.First();
//get all ImageParts in the first slide
List<ImagePart> imageParts = new List<ImagePart>();
part.GetPartsOfType<ImagePart>(imageParts);
foreach (ImagePart imagePart in imageParts)
{
//find the picture related to the image
Picture pic = part.Slide.Descendants<Picture>().Where(p =>
p.BlipFill.Blip.Embed == part.GetIdOfPart(imagePart)).FirstOrDefault();
//Output the Title property
Console.WriteLine(pic.NonVisualPictureProperties.NonVisualDrawingProperties.Title);
}
}
Upvotes: 6