Search code examples
c#openxmldocxopenxml-sdk

Resize existing image in DocX using OpenXML sdk


Got template docx with image placeholder which replaced by correct picture.

private void SetImagePartData(ImagePart imagePart, byte[] data)
{
    if (imagePart != null)
    {
        using (var writer = new BinaryWriter(imagePart.GetStream()))
        {
            writer.Write(data);
        }
    }
}

but it preserves placeholder size. How to change it to actual image size? Byte array is aqquared from image on server, so size is known.


Solution

  • If you mean a content control with your placeholder you can use following code I once needed:

    //Get SdtElement (can be a block, run... so I use the base class) with corresponding Tag
    SdtElement block = doc.MainDocumentPart.Document.Body.Descendants<SdtElement>()
      .FirstOrDefault(sdt => sdt.SdtProperties.GetFirstChild<Tag>()?.Val == contentControlTag);
    
    //Get First drawing Element and get the original sizes of placeholder SDT
    //I use SDT placeholder size as maximum size to calculate picture size with correct ratios
    Drawing sdtImage = block.Descendants<Drawing>().First();
    double sdtWidth = sdtImage.Inline.Extent.Cx;
    double sdtHeight = sdtImage.Inline.Extent.Cy;
    double sdtRatio = sdtWidth / sdtHeight;
    
    *Calculate final width/height of image*
    
    //Resize picture placeholder
    sdtImage.Inline.Extent.Cx = finalWidth;
    sdtImage.Inline.Extent.Cy = finalHeight;
    
    //Change width/height of picture shapeproperties Transform
    //This will override above height/width until you manually drag image for example
    sdtImage.Inline.Graphic.GraphicData
        .GetFirstChild<DocumentFormat.OpenXml.Drawing.Pictures.Picture>()
        .ShapeProperties.Transform2D.Extents.Cx = finalWidth;
    sdtImage.Inline.Graphic.GraphicData
        .GetFirstChild<DocumentFormat.OpenXml.Drawing.Pictures.Picture>()
        .ShapeProperties.Transform2D.Extents.Cy = finalHeight;
    

    But you can use it if you are just using an image in your word document too. You just need to locate the correct Drawing element which contains the reference to your imagepart. Then you can use the bottom part of the code to adjust the image size. It's important you adjust both the Transform2D x and y as well as the Inline x and y or the image size won't be changed.