Skip to content

.NET 操作 PowerPoint COM 组件:从零到精通的幻灯片制作实战

图片与媒体素材处理

问题

文字稿加上配图才是一份完整的 PPT。但把一张图片塞进幻灯片,涉及到坐标换算、文件格式、链接 vs 嵌入、裁剪旋转,任何一个环节不对,生成出来的画面就歪了。

MudTools 在 IPowerPointShapes 上提供了三种添加图片的路径,分别对应不同的使用场景。

插入本地图片

核心方法:Shapes.AddPictureShapes.AddPicture2。后者多了一个 MsoPictureCompress 参数。

csharp
using var app = PowerPointFactory.BlankDocument();
var pres = app.ActivePresentation;
var slide = pres.AddSlide(PpSlideLayout.ppLayoutBlank);

// 参数: 文件路径, 是否链接, 是否随文档保存, left, top, width, height
var pic = slide.Shapes.AddPicture(
    @"C:\Images\logo.png",
    linkToFile: false,
    saveWithDocument: true,
    left: 100, top: 80,
    width: 200, height: -1  // -1 表示保持原始尺寸
);

关键参数说明:

参数说明
linkToFilefalse = 嵌入文件(PPT 文件体积变大);true = 仅存路径(源文件删了就裂图)
saveWithDocument一般配合 linkToFile=false 使用,必须为 true
width/height-1 表示等比缩放/保持原始尺寸。只传一个 -1,另一个给具体值,会自动等比

实际项目中 99% 的情况是 linkToFile: false, saveWithDocument: true——图片嵌入 PPT,不依赖外部源文件。

尺寸单位:Points vs Pixels

PowerPoint 的坐标系统使用 Points(磅),和屏幕的像素不是一回事。

换算公式:

1 inch = 72 points
1 inch = 96 pixels (标准 96 DPI 屏幕)

1 point = 96/72 ≈ 1.333 pixels

所以在代码里写 left: 144 表示距离左边 2 英寸(约 5cm)。一个常见的全幅图片尺寸:

csharp
// 10英寸 × 7.5英寸 → 720pt × 540pt(标准 4:3 幻灯片内容区)
slide.Shapes.AddPicture(
    @"C:\bg.jpg", false, true,
    0, 0, 720, 540
);

如果你手头只有像素值,先除以 96 再乘 72 转成磅:

csharp
float PxToPt(int pixels) => pixels * 72f / 96f;

插入网络图片

AddPicture 不支持 URL。你需要先下载到本地临时文件,再嵌入:

csharp
using var httpClient = new HttpClient();
var imageBytes = await httpClient.GetByteArrayAsync(
    "https://example.com/chart.png");

string tempFile = Path.GetTempFileName() + ".png";
await File.WriteAllBytesAsync(tempFile, imageBytes);

try
{
    var pic = slide.Shapes.AddPicture(tempFile, false, true, 50, 50, 500, 300);
}
finally
{
    File.Delete(tempFile);
}

图片定位:Left / Top / Width / Height

图片插入后,这四个属性随时可以改:

csharp
pic.Left = 50;     // 距离幻灯片左边 50pt
pic.Top = 120;     // 距离幻灯片顶部 120pt
pic.Width = 400;   // 宽度
pic.Height = 300;  // 高度
pic.LockAspectRatio = true;  // 锁定宽高比

锁定宽高比之后,改 Width 会自动等比更新 Height,反之亦然。

裁剪

MudTools 的 IPowerPointShape 提供了四个方向的裁剪方法,都是基于 CanvasCropXxx

csharp
// 从左边裁掉 20pt
pic.CanvasCropLeft(20);

// 从右边裁掉 30pt
pic.CanvasCropRight(30);

// 从顶部裁掉 10pt
pic.CanvasCropTop(10);

// 从底部裁掉 15pt
pic.CanvasCropBottom(15);

裁剪的单位也是磅。图片在裁剪后不会拉伸,只是显示区域缩小了。裁剪掉的原始像素还在文件里,可以通过恢复 PictureFormat 的裁剪值找回。

旋转与翻转

csharp
// 旋转 45 度
pic.Rotation = 45;

// 水平翻转
pic.Flip(MsoFlipCmd.msoFlipHorizontal);

// 垂直翻转
pic.Flip(MsoFlipCmd.msoFlipVertical);

Rotation 正值为顺时针旋转。多个 IncrementRotation 调用会累加。

透明度与边框

图片本身没有直接的透明度属性——透明度其实是形状的填充图片属性。但对于 AddPicture 插入的自选图片形状,可以通过它内部的填充格式来调:

csharp
// 调整亮度/对比度(通过 PictureFormat)
pic.PictureFormat.Brightness = 0.5f;    // 0.0 ~ 1.0
pic.PictureFormat.Contrast = 0.3f;

// 给图片加边框
pic.Line.ForeColor.RGB = 0x3498DB;      // 蓝色边框
pic.Line.Weight = 2;                    // 2pt 粗细
pic.Line.DashStyle = MsoLineDashStyle.msoLineSolid;

IPowerPointPictureFormat 完整字段:

属性类型说明
Brightnessfloat亮度(0~1)
Contrastfloat对比度(0~1)
CropLeftfloat左侧裁剪量
CropTopfloat顶部裁剪量
CropRightfloat右侧裁剪量
CropBottomfloat底部裁剪量
TransparencyColorint透明色 RGB
TransparentBackgroundbool是否透明背景
mermaid
flowchart LR
    A["AddPicture(file, linkToFile, saveWithDocument,\nleft, top, width, height)"] --> B{"linkToFile?"}
    B -->|"false"| C["图片嵌入 PPT\n文件体积增大\n不依赖外部路径"]
    B -->|"true"| D["仅保存路径引用\nPPT 文件小\n源文件删除→裂图"]
    C --> E["saveWithDocument=true<br/>(必须)"]
    D --> F["saveWithDocument 被忽略"]

音频与视频

IPowerPointShapes 提供了 AddMediaObjectAddMediaObject2 两个方法。

csharp
var media = slide.Shapes.AddMediaObject2(
    @"C:\Media\intro.mp4",
    linkToFile: false,
    saveWithDocument: true,
    left: 50, top: 200,
    width: 500, height: 350
);

// 配置播放触发器
media.AnimationSettings.PlaySettings.PlayOnEntry = true;
media.AnimationSettings.PlaySettings.LoopUntilStopped = false;
media.AnimationSettings.PlaySettings.HideWhileNotPlaying = true;

AddMediaObject2 增加了一个 MsoPictureCompress 参数,可以控制多媒体文件的压缩策略:

csharp
var media = slide.Shapes.AddMediaObject2(
    @"C:\Media\presentation.mp4",
    linkToFile: false,
    saveWithDocument: true,
    left: 50, top: 200,
    width: 500, height: 350,
    compress: MsoPictureCompress.msoPictureCompressDocDefault
);

支持的媒体格式取决于 PowerPoint 版本和系统解码器。一般来说 MP4(H.264)兼容性最好,WAV 用于短音效。

完整示例:图文排版页面

csharp
using MudTools.OfficeInterop;
using MudTools.OfficeInterop.PowerPoint;

using var app = PowerPointFactory.BlankDocument();
var pres = app.ActivePresentation;
var slide = pres.AddSlide(PpSlideLayout.ppLayoutBlank);

// 背景图铺满
slide.Shapes.AddPicture(
    @"C:\Images\bg.jpg", false, true,
    0, 0, 720, 540);

// Logo 放在左上角
var logo = slide.Shapes.AddPicture(
    @"C:\Images\logo.png", false, true,
    20, 20, 120, -1);  // 宽度 120pt,高度自动等比
logo.LockAspectRatio = true;

// 标题文字(用文本框覆盖在图片上)
var titleBox = slide.Shapes.AddTextbox(
    MsoTextOrientation.msoTextOrientationHorizontal,
    60, 200, 600, 80);
titleBox.TextFrame.TextRange.Text = "2026 产品发布会";
titleBox.TextFrame.TextRange.Font.Size = 44;
titleBox.TextFrame.TextRange.Font.Bold = true;
titleBox.TextFrame.TextRange.Font.Color.RGB = 0xFFFFFF;
titleBox.TextFrame.TextRange.Font.NameFarEast = "微软雅黑";

// 产品截图(带边框)
var productPic = slide.Shapes.AddPicture(
    @"C:\Images\product.png", false, true,
    60, 320, 400, 250);
productPic.Line.Weight = 3;
productPic.Line.ForeColor.RGB = 0x3498DB;

// 右下角带透明度的水印
var watermark = slide.Shapes.AddPicture(
    @"C:\Images\watermark.png", false, true,
    500, 400, 180, -1);
watermark.PictureFormat.TransparentBackground = true;

Console.WriteLine("图文排版完成,按回车退出...");
Console.ReadLine();

小结

图片处理的核心把握好三个维度:嵌入 vs 链接决定了文件分发方式;Points 单位换算决定了排版位置;裁剪与锁定宽高比决定了显示效果。音频和视频的路径同理,区别在于 AddMediaObject2 多了压缩选项。

下一篇文章聚焦表格——动态行列生成、单元格内容设置和样式美化。