Open XML: add a picture

Within this article I want to show how to add a picture to an Open XML document.

 
Document Image Part
At first you have to create an image part. This document part is used to store the image. If you use an existing image file, you may use a FileStream to read the file content. Afterwards you can use the stream data to feed the image part. The following source code shows an according example.

//file name
string folder = @"...";
string fileName = folder + @"\Test.docx";
string imageFileName = folder + @"\image.png";

//create file
using (var file = WordprocessingDocument.Create(
    fileName, WordprocessingDocumentType.Document))
{
    file.AddMainDocumentPart();

    //add image part and add image from file
    ImagePart imagePart = file.MainDocumentPart.AddImagePart(ImagePartType.Png);

    using (FileStream stream = new FileStream(imageFileName, FileMode.Open))
    {
        imagePart.FeedData(stream);
    }
}

 
Image Element
Next you can use the image within your document. To do so you have to create a Drawing element with you image. Unfortunately it isn’t easy to create this element because it is necessary to define a lot of parameters. Therefore I have created a function which will create the Drawing. This functions needs the ID of the Image Part and the size of the target image element. The following source code shows the function to load the Image. Within this article I don’t want to explain every detail and the used objects. But you can use the function as it is and adapt it if you want to set some additional parameters.

private static Drawing GetImageElement(
    string imagePartId,
    string fileName,
    string pictureName,
    double width,
    double height)
{
    double englishMetricUnitsPerInch = 914400;
    double pixelsPerInch = 96;

    //calculate size in emu
    double emuWidth = width * englishMetricUnitsPerInch / pixelsPerInch;
    double emuHeight = height * englishMetricUnitsPerInch / pixelsPerInch;

    var element = new Drawing(
        new XmlDrawing.Wordprocessing.Inline(
            new XmlDrawing.Wordprocessing.Extent { Cx = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight },
            new XmlDrawing.Wordprocessing.EffectExtent { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
            new XmlDrawing.Wordprocessing.DocProperties { Id = (UInt32Value)1U, Name = pictureName },
            new XmlDrawing.Wordprocessing.NonVisualGraphicFrameDrawingProperties(
            new XmlDrawing.GraphicFrameLocks { NoChangeAspect = true }),
            new XmlDrawing.Graphic(
                new XmlDrawing.GraphicData(
                    new XmlDrawing.Pictures.Picture(
                        new XmlDrawing.Pictures.NonVisualPictureProperties(
                            new XmlDrawing.Pictures.NonVisualDrawingProperties { Id = (UInt32Value)0U, Name = fileName },
                            new XmlDrawing.Pictures.NonVisualPictureDrawingProperties()),
                        new XmlDrawing.Pictures.BlipFill(
                            new XmlDrawing.Blip(
                                new XmlDrawing.BlipExtensionList(
                                    new XmlDrawing.BlipExtension { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }))
                                    {
                                        Embed = imagePartId,
                                        CompressionState = XmlDrawing.BlipCompressionValues.Print
                                    },
                                    new XmlDrawing.Stretch(new XmlDrawing.FillRectangle())),
                        new XmlDrawing.Pictures.ShapeProperties(
                            new XmlDrawing.Transform2D(
                                new XmlDrawing.Offset { X = 0L, Y = 0L },
                                new XmlDrawing.Extents { Cx = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight }),
                            new XmlDrawing.PresetGeometry(
                                new XmlDrawing.AdjustValueList()) { Preset = XmlDrawing.ShapeTypeValues.Rectangle })))
                {
                    Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
                }))
            {
                DistanceFromTop = (UInt32Value)0U,
                DistanceFromBottom = (UInt32Value)0U,
                DistanceFromLeft = (UInt32Value)0U,
                DistanceFromRight = (UInt32Value)0U,
                EditId = "50D07946"
            });
    return element;
}

 
Example application
The following code shows the complete example, implemented as console application.

class Program
{
    static void Main(string[] args)
    {
        //file name
        string folder = @"D:\Projekte\Hamilton\Test\OpenXmlSdk\InsertPicture\InsertPicture\bin\Debug";
        string fileName = folder + @"\Test.docx";
        string imageFileName = folder + @"\image.png";

        //create file
        using (var file = WordprocessingDocument.Create(
            fileName, WordprocessingDocumentType.Document))
        {
            file.AddMainDocumentPart();

            //add image part and add image from file
            ImagePart imagePart = file.MainDocumentPart.AddImagePart(ImagePartType.Png);

            using (FileStream stream = new FileStream(imageFileName, FileMode.Open))
            {
                imagePart.FeedData(stream);
            }

            //set content
            var text = new Text("Hello Open XML world");
            var run = new Run(text);
            var paragraph = new Paragraph(run);
            var body = new Body(paragraph);
            var document = new Document(body);

            //add image
            Drawing imageElement = GetImageElement(
                file.MainDocumentPart.GetIdOfPart(imagePart),
                imageFileName,
                "my image",
                22,
                22);

            body.AppendChild(new Paragraph(new Run(imageElement)));
                
            //save
            file.MainDocumentPart.Document = document;
            file.MainDocumentPart.Document.Save();
        }
    }

    private static Drawing GetImageElement(
        string imagePartId,
        string fileName,
        string pictureName,
        double width,
        double height)
    {
        double englishMetricUnitsPerInch = 914400;
        double pixelsPerInch = 96;

        //calculate size in emu
        double emuWidth = width * englishMetricUnitsPerInch / pixelsPerInch;
        double emuHeight = height * englishMetricUnitsPerInch / pixelsPerInch;

        var element = new Drawing(
            new XmlDrawing.Wordprocessing.Inline(
                new XmlDrawing.Wordprocessing.Extent { Cx = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight },
                new XmlDrawing.Wordprocessing.EffectExtent { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
                new XmlDrawing.Wordprocessing.DocProperties { Id = (UInt32Value)1U, Name = pictureName },
                new XmlDrawing.Wordprocessing.NonVisualGraphicFrameDrawingProperties(
                new XmlDrawing.GraphicFrameLocks { NoChangeAspect = true }),
                new XmlDrawing.Graphic(
                    new XmlDrawing.GraphicData(
                        new XmlDrawing.Pictures.Picture(
                            new XmlDrawing.Pictures.NonVisualPictureProperties(
                                new XmlDrawing.Pictures.NonVisualDrawingProperties { Id = (UInt32Value)0U, Name = fileName },
                                new XmlDrawing.Pictures.NonVisualPictureDrawingProperties()),
                            new XmlDrawing.Pictures.BlipFill(
                                new XmlDrawing.Blip(
                                    new XmlDrawing.BlipExtensionList(
                                        new XmlDrawing.BlipExtension { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }))
                                        {
                                            Embed = imagePartId,
                                            CompressionState = XmlDrawing.BlipCompressionValues.Print
                                        },
                                        new XmlDrawing.Stretch(new XmlDrawing.FillRectangle())),
                            new XmlDrawing.Pictures.ShapeProperties(
                                new XmlDrawing.Transform2D(
                                    new XmlDrawing.Offset { X = 0L, Y = 0L },
                                    new XmlDrawing.Extents { Cx = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight }),
                                new XmlDrawing.PresetGeometry(
                                    new XmlDrawing.AdjustValueList()) { Preset = XmlDrawing.ShapeTypeValues.Rectangle })))
                    {
                        Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
                    }))
                {
                    DistanceFromTop = (UInt32Value)0U,
                    DistanceFromBottom = (UInt32Value)0U,
                    DistanceFromLeft = (UInt32Value)0U,
                    DistanceFromRight = (UInt32Value)0U,
                    EditId = "50D07946"
                });
        return element;
    }
}
Werbung
Dieser Beitrag wurde unter .NET, C#, Open XML veröffentlicht. Setze ein Lesezeichen auf den Permalink.

3 Antworten zu Open XML: add a picture

  1. Martin Weihrauch schreibt:

    I cannot get this to work as I dont know any class named: new XmlDrawing
    Can you help?

    • Anonymous schreibt:

      using System.IO;
      using DocumentFormat.OpenXml;
      using DocumentFormat.OpenXml.Packaging;
      using DocumentFormat.OpenXml.Wordprocessing;
      using A = DocumentFormat.OpenXml.Drawing;
      using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
      using PIC = DocumentFormat.OpenXml.Drawing.Pictures;

  2. Stacy Morley schreibt:

    Helloo mate great blog post

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s