从 Node.js 中演示文稿形状提取图像
概述
演示文稿中的图像可以出现在多种形状类型中:普通图片框、作为形状填充的图片、OLE 对象预览图像、视频或音频帧的缩略图、缩放图像,或嵌套在表格、图表和 SmartArt 形状内部的图像。Aspose.Slides 将这些图像存储在演示文稿的图像集合中,可通过 ImageCollection 和 PPImage 对象访问。
如果您只需导出演示文稿中嵌入的每个图像资源,可遍历 presentation.getImages()。本文关注的是另一项任务:遍历形状以查找图像在幻灯片上的使用位置,从而保存的文件能够保留有用的上下文信息,例如幻灯片编号、形状位置和来源类型(图片框、填充图像、媒体预览、OLE 预览或缩放图像)。
共享帮助方法
下面的帮助方法使示例保持简洁。saveOriginalImage 写入原始嵌入的字节,根据 MIME 类型选择安全的扩展名,并通过 SHA-256 哈希跳过重复的图像二进制数据。
const fileSystem = require("fs");
const pathModule = require("path");
const cryptoModule = require("crypto");
const asposeSlides = require("aspose.slides.via.java");
class ShapeReference {
constructor(shape, namePart) {
this.shape = shape;
this.namePart = namePart;
}
}
function saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes) {
const imageData = image.getBinaryData();
const imageBuffer = Buffer.from(imageData);
const imageHash = getSha256Hash(imageBuffer);
if (savedImageHashes.has(imageHash)) {
return false;
}
savedImageHashes.add(imageHash);
const extension = getExtensionFromContentType(image.getContentType());
const fileName = `${fileNameBase}.${extension}`;
const outputPath = pathModule.join(outputDirectory, fileName);
fileSystem.writeFileSync(outputPath, imageBuffer);
return true;
}
function saveImageAsPng(image, outputDirectory, fileNameBase) {
const fileName = `${fileNameBase}.png`;
const outputPath = pathModule.join(outputDirectory, fileName);
const outputImage = image.getImage();
try {
outputImage.save(outputPath, asposeSlides.ImageFormat.Png);
} finally {
if (outputImage !== null) {
outputImage.dispose();
}
}
}
function getPictureFillImage(fillFormat) {
if (fillFormat == null || fillFormat.getFillType() !== asposeSlides.FillType.Picture) {
return null;
}
return fillFormat.getPictureFillFormat().getPicture().getImage();
}
function enumerateShapes(shapes, prefix, includeGroupedShapes) {
const shapeReferences = [];
const shapeCount = shapes.size();
for (let shapeIndex = 0; shapeIndex < shapeCount; shapeIndex++) {
const shape = shapes.get_Item(shapeIndex);
const displayIndex = shapeIndex + 1;
const shapeNamePart = `${prefix}_shape_${displayIndex}`;
const shapeReference = new ShapeReference(shape, shapeNamePart);
shapeReferences.push(shapeReference);
if (includeGroupedShapes && java.instanceOf(shape, "com.aspose.slides.GroupShape")) {
const childShapes = shape.getShapes();
const childReferences = enumerateShapes(childShapes, shapeNamePart, includeGroupedShapes);
shapeReferences.push(...childReferences);
}
}
return shapeReferences;
}
function getSha256Hash(data) {
return cryptoModule.createHash("sha256").update(data).digest("hex");
}
function getExtensionFromContentType(contentType) {
if (contentType == null || contentType.trim().length === 0) {
return "bin";
}
const mediaType = contentType.split(";")[0].trim().toLowerCase();
if (mediaType === "image/jpeg") {
return "jpg";
}
if (mediaType === "image/png") {
return "png";
}
if (mediaType === "image/gif") {
return "gif";
}
if (mediaType === "image/bmp") {
return "bmp";
}
if (mediaType === "image/tiff") {
return "tiff";
}
if (mediaType === "image/x-emf" || mediaType === "image/emf") {
return "emf";
}
if (mediaType === "image/x-wmf" || mediaType === "image/wmf") {
return "wmf";
}
if (mediaType === "image/svg+xml") {
return "svg";
}
if (mediaType.startsWith("image/")) {
const extension = mediaType.substring("image/".length);
return makeSafeFileNamePart(extension);
}
return "bin";
}
function makeSafeFileNamePart(value) {
return value.replace(/[^A-Za-z0-9._-]/g, "_");
}
从图片框提取图像
当图片作为独立对象插入时使用此方法。PictureFrame 将其图片存储在 getPictureFormat().getPicture().getImage() 中,该方法返回一个 PPImage 对象。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "extracted-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, false);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.PictureFrame")) {
const pictureFrame = shapeReference.shape;
const image = pictureFrame.getPictureFormat().getPicture().getImage();
saveOriginalImage(image, outputDirectory, shapeReference.namePart, savedImageHashes);
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从填充图片的形状提取图像
形状可以使用图片作为填充。首先检查形状的填充类型:如果不是 FillType.Picture,则该填充不包含可提取的图片。下面的示例处理 AutoShape 对象,并通过 PPImage 的 getImage() 方法将每个图像保存为 PNG。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "shape-fill-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, false);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.AutoShape")) {
const autoShape = shapeReference.shape;
const fillFormat = autoShape.getFillFormat();
const image = getPictureFillImage(fillFormat);
if (image !== null) {
saveImageAsPng(image, outputDirectory, shapeReference.namePart);
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从 OLE 对象框提取预览图像
OleObjectFrame 可以拥有 PowerPoint 用作对象在幻灯片上预览的替代图片。该图像可通过 getSubstitutePictureFormat().getPicture().getImage() 获得。提取此图片得到的是预览图像,而不是嵌入的 OLE 包内容。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "ole-preview-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, false);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.OleObjectFrame")) {
const oleObjectFrame = shapeReference.shape;
const image = oleObjectFrame.getSubstitutePictureFormat().getPicture().getImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_ole_preview`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从视频帧提取预览图像
VideoFrame 也可以在 getPictureFormat().getPicture().getImage() 中存储预览图像。这是幻灯片上显示的海报或缩略图,而不是从视频流解码的帧。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "video-preview-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, false);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.VideoFrame")) {
const videoFrame = shapeReference.shape;
const image = videoFrame.getPictureFormat().getPicture().getImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_video_preview`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从音频帧提取预览图像
AudioFrame 可以在 getPictureFormat().getPicture().getImage() 中存储缩略图。这是幻灯片上音频对象显示的图像。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "audio-preview-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, false);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.AudioFrame")) {
const audioFrame = shapeReference.shape;
const image = audioFrame.getPictureFormat().getPicture().getImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_audio_preview`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从缩放对象提取图像
ZoomFrame 和 SectionZoomFrame 形状可以使用自定义图像。请从缩放框读取 getZoomImage()。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "zoom-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, false);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.ZoomFrame")) {
const zoomFrame = shapeReference.shape;
const image = zoomFrame.getZoomImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_zoom`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
continue;
}
}
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.SectionZoomFrame")) {
const sectionZoomFrame = shapeReference.shape;
const image = sectionZoomFrame.getZoomImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_section_zoom`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
continue;
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从概览缩放框提取图像
SummaryZoomFrame 也是一种形状。其各节项可以使用自定义图像,通过每个概览缩放节的 getZoomImage() 方法获取。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "summary-zoom-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, false);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.SummaryZoomFrame")) {
const summaryZoomFrame = shapeReference.shape;
const summaryZoomCollection = summaryZoomFrame.getSummaryZoomCollection();
const sectionCount = summaryZoomCollection.size();
for (let sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
const summaryZoomSection = summaryZoomCollection.get_Item(sectionIndex);
const image = summaryZoomSection.getZoomImage();
if (image !== null) {
const displayIndex = sectionIndex + 1;
const fileNameBase = `${shapeReference.namePart}_summary_zoom_${displayIndex}`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从表格形状提取图像
Table 是一种形状。表格中的图像通常存储为单元格的图片填充。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "table-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, true);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.Table")) {
const table = shapeReference.shape;
const rowCount = table.getRows().size();
const columnCount = table.getColumns().size();
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
const cell = table.get_Item(columnIndex, rowIndex);
const fillFormat = cell.getCellFormat().getFillFormat();
const image = getPictureFillImage(fillFormat);
if (image !== null) {
const displayRow = rowIndex + 1;
const displayColumn = columnIndex + 1;
const fileNameBase = `${shapeReference.namePart}_cell_${displayRow}_${displayColumn}`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
}
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从图表形状提取图像
Chart 是一种形状。下面的示例从图表区域的图片填充中提取图像。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "chart-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, true);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.Chart")) {
const chart = shapeReference.shape;
const fillFormat = chart.getFillFormat();
const image = getPictureFillImage(fillFormat);
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_chart_area`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
从 SmartArt 形状提取图像
SmartArt 对象是一种形状。根据 SmartArt 布局,图像可能存储在节点项目符号填充中或节点形状的填充格式中。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "smartart-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, true);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.SmartArt")) {
const smartArt = shapeReference.shape;
const allNodes = smartArt.getAllNodes();
const nodeCount = allNodes.size();
for (let nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
const node = allNodes.get_Item(nodeIndex);
const bulletFillFormat = node.getBulletFillFormat();
const bulletImage = getPictureFillImage(bulletFillFormat);
if (bulletImage !== null) {
const displayNode = nodeIndex + 1;
const fileNameBase = `${shapeReference.namePart}_smartart_node_${displayNode}_bullet`;
saveOriginalImage(bulletImage, outputDirectory, fileNameBase, savedImageHashes);
}
const nodeShapes = node.getShapes();
const nodeShapeCount = nodeShapes.size();
for (let nodeShapeIndex = 0; nodeShapeIndex < nodeShapeCount; nodeShapeIndex++) {
const nodeShape = nodeShapes.get_Item(nodeShapeIndex);
const fillFormat = nodeShape.getFillFormat();
const image = getPictureFillImage(fillFormat);
if (image !== null) {
const displayNode = nodeIndex + 1;
const displayNodeShape = nodeShapeIndex + 1;
const fileNameBase = `${shapeReference.namePart}_smartart_node_${displayNode}_shape_${displayNodeShape}`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
}
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
在组合形状中包含图像
组合形状包含其自己的形状集合。共享的 enumerateShapes 帮助方法具有 includeGroupedShapes 选项。当您想检查 GroupShape 对象内部的形状时,将其设为 true。下面的示例提取图片框、填充图片的形状、OLE 对象预览、视频帧缩略图和音频帧缩略图中的图像。要同时包含表格、图表、SmartArt 和概览缩放图像,请复用前述章节的专用提取逻辑,并保持相同的递归形状遍历。
const inputPath = "sample.pptx";
const currentDirectory = process.cwd();
const outputDirectory = pathModule.join(currentDirectory, "all-shape-images");
fileSystem.mkdirSync(outputDirectory, { recursive: true });
const savedImageHashes = new Set();
const presentation = new asposeSlides.Presentation(inputPath);
try {
const slideCount = presentation.getSlides().size();
for (let slideIndex = 0; slideIndex < slideCount; slideIndex++) {
const slide = presentation.getSlides().get_Item(slideIndex);
const slideNumber = slide.getSlideNumber();
const slidePrefix = `slide_${slideNumber}`;
const shapes = slide.getShapes();
const shapeReferences = enumerateShapes(shapes, slidePrefix, true);
for (const shapeReference of shapeReferences) {
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.OleObjectFrame")) {
const oleObjectFrame = shapeReference.shape;
const image = oleObjectFrame.getSubstitutePictureFormat().getPicture().getImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_ole_preview`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
continue;
}
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.VideoFrame")) {
const videoFrame = shapeReference.shape;
const image = videoFrame.getPictureFormat().getPicture().getImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_video_preview`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
continue;
}
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.AudioFrame")) {
const audioFrame = shapeReference.shape;
const image = audioFrame.getPictureFormat().getPicture().getImage();
if (image !== null) {
const fileNameBase = `${shapeReference.namePart}_audio_preview`;
saveOriginalImage(image, outputDirectory, fileNameBase, savedImageHashes);
}
continue;
}
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.PictureFrame")) {
const pictureFrame = shapeReference.shape;
const image = pictureFrame.getPictureFormat().getPicture().getImage();
saveOriginalImage(image, outputDirectory, shapeReference.namePart, savedImageHashes);
continue;
}
if (java.instanceOf(shapeReference.shape, "com.aspose.slides.AutoShape")) {
const autoShape = shapeReference.shape;
const fillFormat = autoShape.getFillFormat();
const image = getPictureFillImage(fillFormat);
if (image !== null) {
saveOriginalImage(image, outputDirectory, shapeReference.namePart, savedImageHashes);
}
}
}
}
} finally {
if (presentation !== null) {
presentation.dispose();
}
}
边缘情况和实用说明
- 重复图像: 多个形状可能引用相同的图像,或是字节相同的不同图像。在写入文件之前,对
getBinaryData()返回的 PPImage 数据进行哈希,以实现每个唯一图像仅输出一个文件。 - 原始数据 与 转换后输出: 从
getBinaryData()中保存 PPImage 数据可保留嵌入的 JPEG、PNG、GIF、SVG、EMF 或 WMF 数据。当您希望统一输出格式时,保存getImage()返回的图像会更有用。 - 不支持的填充类型: 实心、渐变、图案和无填充的形状不包含图片填充。在读取
getPictureFillFormat()之前,请检查 FillType。 - 组合形状: 顶层幻灯片形状集合不会展开组合。若组合内容重要,请通过
getShapes()递归检查 GroupShape 的内容。 - OLE 对象预览: OleObjectFrame 可能通过
getSubstitutePictureFormat()提供预览图像,但该图像仅是幻灯片预览,而不是 OLE 对象内部的嵌入文件。 - 视频帧缩略图: VideoFrame 可能通过
getPictureFormat()提供预览图像,但该图像仅是幻灯片上显示的海报,而不是从视频流中提取的。 - 音频帧缩略图: AudioFrame 可能通过
getPictureFormat()提供图标或缩略图;这并非嵌入的音频数据。 - 缩放图像: 幻灯片缩放、节缩放和概览缩放形状可能通过
getZoomImage()使用自定义的 PPImage 对象。 - 嵌套形状模型: 表格、图表和 SmartArt 对象实现了 Shape,但它们的图像通常存储在嵌套的表格单元格、图表元素或 SmartArt 节点的格式对象中。
- 裁剪或变换的图片: 访问 PPImage 可获得存储的图像资源。它不会呈现形状所施加的裁剪、透明度、重新着色、旋转或其他视觉效果。
常见问题
我可以提取原始图像而不进行裁剪、特效或形状转换吗?
可以。访问 PPImage 对象并将 getBinaryData() 的数据写入磁盘。这会保留演示文稿中存储的原始编码图像,而不是图像在幻灯片上的渲染方式。
我可以将所有提取的图像导出为 PNG 吗?
可以。使用 PPImage 及其 getImage() 方法,然后使用 ImageFormat 调用 save()。这会转换输出,可能无法保留原始文件类型或矢量数据。
如何避免多次保存相同的图像?
对 getBinaryData() 返回的 PPImage 数据计算哈希并将哈希存入集合。若新图像的哈希已存在,则跳过或记录对已有输出文件的另一次引用。
为什么某些形状未生成图像?
图片框、填充图片的形状、OLE 对象框、媒体框、缩放框、表格、图表和 SmartArt 对象都可能引用图像。某些形状类型通过嵌套的格式对象公开图像,因此仅检查 getPictureFormat() 或形状的 getFillFormat() 并不总是足够。
我可以提取视频帧显示的缩略图吗?
可以。使用 VideoFrame 并读取 getPictureFormat().getPicture().getImage()。这会提取随视频帧存储的海报图像,而不是从视频文件生成的帧。
如何确定演示文稿图像集合中的特定图像被哪些形状使用?
Aspose.Slides 不会存储从 PPImage 到形状的反向链接。遍历时构建映射:每当发现图像引用时,记录幻灯片编号、形状路径以及图像哈希或集合项。
我可以提取嵌入在 OLE 对象内部的图像,例如附件文档吗?
您可以从 OleObjectFrame 提取 OLE 对象的幻灯片预览。但该预览并不是嵌入的文档本身。若要提取嵌入文件内部的图像,需要先提取 OLE 数据,再使用相应文件类型的工具进行检查。