如何使用c#和OpenXML在PowerPoint演示文稿中调整大小和图像

时间:2016-03-14 12:46:00

标签: c# powerpoint openxml

道歉,如果这已经得到回答,但我已经看到很多相似的帖子,到目前为止没有任何帮助我。

基本上我正在构建一个采用PowerPoint模板的应用程序,并替换来自数据库的文本和图像。大部分都是完整的,但是当我更换图像时,我正在努力解决问题。模板中插入了大量空白图像,可以替换它们,因为它们只是占位符所以它们都是方形的。我可以毫无问题地替换它们,但新图像可以垂直或水平拉伸,具体取决于我从数据库中提取的图像。它基本上填充了占位符的形状。

我必须承认我发现很难理解文档模型所以也许我试图改变错误的东西,我试图改变blip.parent.shape的“范围”属性但是我猜测并没有得到快乐。

下面是代码交换图片的工作原理(归功于原作者amos http://atakala.com/browser/Item.aspx?user_id=amos&dict_id=2291)。我不确定在图像到位或之前,甚至尝试调整大小的地方......任何帮助都会非常感激。我现在并不担心实际尺寸,我可以自己计算,它只是能够改变图像尺寸,这是问题所在。

除了示例代码(可能没那么有用),我已经链接到我的示例项目。样本和文件都应该放在c:\ test中才能工作。它只是一些图像,c#项目和program.cs文件,以及一个示例PPTX文件。

DOWNLOAD Sample zip file

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using d = DocumentFormat.OpenXml.Drawing;
using System.IO;

namespace PPTX_Image_Replace_test
{
class Program
{
    static void Main(string[] args)
    {
        TestImageReplace(@"C:\test\TestImageReplaceAndResize.pptx");
    }

    public static void TestImageReplace(string fileName)
    {
        // make a copy of the original and edit that
        string outputFileName = Path.Combine(Path.GetDirectoryName(fileName), "New_" + Path.GetFileName(fileName));
        File.Copy(fileName, outputFileName,true);


        using (PresentationDocument document = PresentationDocument.Open(outputFileName, true))
        {
            ReplaceFirstImageMatchingAltText(document, @"C:\test\Arrow_UP.png", "changeme");
        }
    }

    public static void ReplaceFirstImageMatchingAltText(PresentationDocument presentationDocument, string newImagePath, string alternateTextToFind)
    {
        OpenXmlElementList slideIds = presentationDocument.PresentationPart.Presentation.SlideIdList.ChildElements;

        foreach (SlideId sID in slideIds) // loop thru the SlideIDList
        {
            string relId = sID.RelationshipId; // get first slide relationship
            SlidePart slide = (SlidePart)presentationDocument.PresentationPart.GetPartById(relId); // Get the slide part from the relationship ID. 

            var pictures = slide.Slide.Descendants<ShapeTree>().First().Descendants<Picture>().ToList();
            foreach (var picture in pictures)
            {
                // get photo desc to see if it matches search text 
                var nonVisualPictureProperties = picture.Descendants<NonVisualPictureProperties>().FirstOrDefault();
                if (nonVisualPictureProperties == null)
                    continue;
                var nonVisualDrawingProperties99 = nonVisualPictureProperties.Descendants<NonVisualDrawingProperties>().FirstOrDefault();
                if (nonVisualDrawingProperties99 == null)
                    continue;
                var desc = nonVisualDrawingProperties99.Description;
                if (desc == null || desc.Value == null || !desc.Value.Contains(alternateTextToFind))
                    continue;

                BlipFill blipFill = picture.Descendants<BlipFill>().First();
                var blip = blipFill.Descendants<DocumentFormat.OpenXml.Drawing.Blip>().First();
                string embedId = blip.Embed; // now we need to find the embedded content and update it. 


                // find the content 
                ImagePart imagePart = (ImagePart)slide.GetPartById(embedId);
                if (imagePart != null)
                {
                    using (FileStream fileStream = new FileStream(newImagePath, FileMode.Open))
                    {
                        imagePart.FeedData(fileStream);
                        fileStream.Close();
                    }

                    return; // found the photo and replaced it. 
                }
            }
        }
    }
}
}

1 个答案:

答案 0 :(得分:1)

通常情况下,在我发布问题的几天之后,我会找到答案!最后它非常简单。

我已经有了对图片的引用,所以我只是修改了那里的trasnform,最后一段代码现在看起来像这样..

                // find the content 
                ImagePart imagePart = (ImagePart)slide.GetPartById(embedId);
                if (imagePart != null)
                {

                    d.Transform2D transform =  picture.Descendants<d.Transform2D>().First();
                    transform.Extents.Cx = 800000; // replace with correct calcualted values eventually
                    transform.Extents.Cy = 400000; // replace with correct calculated values eventually

                    using (FileStream fileStream = new FileStream(newImagePath, FileMode.Open))
                    {
                        imagePart.FeedData(fileStream);
                        fileStream.Close();
                    }

                    return; // found the photo and replaced it. 
                }

猜猜我只是看不到树上的木头.......