從 PHP 投影片形狀中提取影像
概觀
投影片中的影像可以出現在多種形狀類型中:普通的圖片框、套用於形狀的圖片填充、OLE 物件預覽影像、影片或音訊框的縮圖、縮放影像,或是嵌入於表格、圖表和 SmartArt 形狀中的影像。Aspose.Slides 將這些影像儲存在投影片影像集合中,可透過 ImageCollection 與 PPImage 物件存取。
如果您只需要匯出投影片中嵌入的每個影像資源,只要遍歷 presentation->getImages() 即可。本篇說明的是另一項任務:遍歷形狀以找出投影片上使用影像的位置,讓儲存的檔案保留有用的上下文資訊,例如投影片編號、形狀位置與來源類型(圖片框、填充影像、媒體預覽、OLE 預覽或縮放影像)。
共享輔助方法
以下的輔助方法讓範例保持簡潔。saveOriginalImage 會寫入原始嵌入的位元組,根據 MIME 類型選擇安全的副檔名,並透過 SHA-256 雜湊跳過重複的影像二進位資料。
use aspose\slides\FillType;
use aspose\slides\ImageFormat;
class ShapeReference
{
public $shape;
public $namePart;
public function __construct($shape, $namePart)
{
$this->shape = $shape;
$this->namePart = $namePart;
}
}
function isNullJava($value)
{
return $value == null || java_is_null($value);
}
function saveOriginalImage($image, $outputDirectory, $fileNameBase, &$savedImageHashes)
{
if (isNullJava($image)) {
return false;
}
$imageData = $image->getBinaryData();
$imageBytes = getBinaryString($imageData);
$imageHash = hash("sha256", $imageBytes);
if (isset($savedImageHashes[$imageHash])) {
return false;
}
$savedImageHashes[$imageHash] = true;
$extension = getExtensionFromContentType($image->getContentType());
$fileName = $fileNameBase . "." . $extension;
$outputPath = $outputDirectory . DIRECTORY_SEPARATOR . $fileName;
file_put_contents($outputPath, $imageBytes);
return true;
}
function saveImageAsPng($image, $outputDirectory, $fileNameBase)
{
if (isNullJava($image)) {
return false;
}
$fileName = $fileNameBase . ".png";
$outputPath = $outputDirectory . DIRECTORY_SEPARATOR . $fileName;
$outputImage = $image->getImage();
try {
$outputImage->save($outputPath, ImageFormat::Png);
} finally {
if (!isNullJava($outputImage)) {
$outputImage->dispose();
}
}
return true;
}
function getPictureFillImage($fillFormat)
{
if (isNullJava($fillFormat) || java_values($fillFormat->getFillType()) != FillType::Picture) {
return null;
}
return $fillFormat->getPictureFillFormat()->getPicture()->getImage();
}
function enumerateShapes($shapes, $prefix, $includeGroupedShapes)
{
$shapeReferences = [];
$shapeCount = java_values($shapes->size());
for ($shapeIndex = 0; $shapeIndex < $shapeCount; $shapeIndex++) {
$shape = $shapes->get_Item($shapeIndex);
$displayIndex = $shapeIndex + 1;
$shapeNamePart = $prefix . "_shape_" . $displayIndex;
$shapeReferences[] = new ShapeReference($shape, $shapeNamePart);
if ($includeGroupedShapes && java_instanceof($shape, new JavaClass("com.aspose.slides.GroupShape"))) {
$childShapes = $shape->getShapes();
$childReferences = enumerateShapes(
$childShapes,
$shapeNamePart,
$includeGroupedShapes
);
$shapeReferences = array_merge($shapeReferences, $childReferences);
}
}
return $shapeReferences;
}
function getBinaryString($binaryData)
{
$bytes = java_values($binaryData);
if (is_string($bytes)) {
return $bytes;
}
$binaryString = "";
foreach ($bytes as $byte) {
$binaryString .= chr($byte & 0xff);
}
return $binaryString;
}
function getExtensionFromContentType($contentType)
{
if ($contentType == null || strlen(trim($contentType)) == 0) {
return "bin";
}
$mediaTypeParts = explode(";", $contentType);
$mediaType = strtolower(trim($mediaTypeParts[0]));
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 (strpos($mediaType, "image/") === 0) {
$extension = substr($mediaType, strlen("image/"));
return makeSafeFileNamePart($extension);
}
return "bin";
}
function makeSafeFileNamePart($value)
{
return preg_replace("/[^A-Za-z0-9._-]/", "_", $value);
}
從圖片框提取影像
此方法適用於以獨立物件插入的圖片。PictureFrame 會將其圖片儲存在 getPictureFormat()->getPicture()->getImage(),該方法回傳一個 PPImage 物件。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "extracted-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, false);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.PictureFrame"))) {
$pictureFrame = $shapeReference->shape;
$image = $pictureFrame->getPictureFormat()->getPicture()->getImage();
saveOriginalImage($image, $outputDirectory, $shapeReference->namePart, $savedImageHashes);
}
}
}
} finally {
$presentation->dispose();
}
從圖像填充的形狀提取影像
形狀可以使用圖片作為填充。首先檢查形狀的填充類型:若不是 FillType.Picture,則該填充中沒有圖片可供提取。以下範例處理 AutoShape 物件,並透過 PPImage 及其 getImage() 方法將每張影像儲存為 PNG。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "shape-fill-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, false);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.AutoShape"))) {
$autoShape = $shapeReference->shape;
$fillFormat = $autoShape->getFillFormat();
$image = getPictureFillImage($fillFormat);
if (!isNullJava($image)) {
saveImageAsPng($image, $outputDirectory, $shapeReference->namePart);
}
}
}
}
} finally {
$presentation->dispose();
}
從 OLE 物件框提取預覽影像
OleObjectFrame 可以有 PowerPoint 用於投影片上物件預覽的替代圖片。此影像可透過 getSubstitutePictureFormat()->getPicture()->getImage() 取得。提取此圖片會得到預覽影像,而非嵌入的 OLE 套件內容。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "ole-preview-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, false);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.OleObjectFrame"))) {
$oleObjectFrame = $shapeReference->shape;
$image = $oleObjectFrame->getSubstitutePictureFormat()->getPicture()->getImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_ole_preview";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
}
}
}
} finally {
$presentation->dispose();
}
從影片框提取預覽影像
VideoFrame 也可以在 getPictureFormat()->getPicture()->getImage() 中儲存預覽影像。這是投影片上顯示的海報或縮圖,並非從影片串流解碼的影格。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "video-preview-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, false);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.VideoFrame"))) {
$videoFrame = $shapeReference->shape;
$image = $videoFrame->getPictureFormat()->getPicture()->getImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_video_preview";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
}
}
}
} finally {
$presentation->dispose();
}
從音訊框提取預覽影像
AudioFrame 可以在 getPictureFormat()->getPicture()->getImage() 中儲存縮圖。這是投影片上音訊物件所顯示的影像。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "audio-preview-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, false);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.AudioFrame"))) {
$audioFrame = $shapeReference->shape;
$image = $audioFrame->getPictureFormat()->getPicture()->getImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_audio_preview";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
}
}
}
} finally {
$presentation->dispose();
}
從縮放物件提取影像
ZoomFrame 與 SectionZoomFrame 形狀可以使用自訂影像。從縮放框讀取 getZoomImage()。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "zoom-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, false);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.ZoomFrame"))) {
$zoomFrame = $shapeReference->shape;
$image = $zoomFrame->getZoomImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_zoom";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
continue;
}
}
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.SectionZoomFrame"))) {
$sectionZoomFrame = $shapeReference->shape;
$image = $sectionZoomFrame->getZoomImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_section_zoom";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
continue;
}
}
}
}
} finally {
$presentation->dispose();
}
從摘要縮放框提取影像
SummaryZoomFrame 也是一種形狀。其各節項目可以使用自訂影像,透過每個摘要縮放節的 getZoomImage() 方法取得。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "summary-zoom-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, false);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.SummaryZoomFrame"))) {
$summaryZoomFrame = $shapeReference->shape;
$summaryZoomCollection = $summaryZoomFrame->getSummaryZoomCollection();
$sectionCount = java_values($summaryZoomCollection->size());
for ($sectionIndex = 0; $sectionIndex < $sectionCount; $sectionIndex++) {
$summaryZoomSection = $summaryZoomCollection->get_Item($sectionIndex);
$image = $summaryZoomSection->getZoomImage();
if (!isNullJava($image)) {
$displayIndex = $sectionIndex + 1;
$fileNameBase = $shapeReference->namePart . "_summary_zoom_" . $displayIndex;
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
}
}
}
}
} finally {
$presentation->dispose();
}
從表格形狀提取影像
Table 為形狀。表格中的影像通常以圖片填充的方式儲存在儲存格內。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "table-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, true);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.Table"))) {
$table = $shapeReference->shape;
$rowCount = java_values($table->getRows()->size());
$columnCount = java_values($table->getColumns()->size());
for ($rowIndex = 0; $rowIndex < $rowCount; $rowIndex++) {
for ($columnIndex = 0; $columnIndex < $columnCount; $columnIndex++) {
$cell = $table->get_Item($columnIndex, $rowIndex);
$fillFormat = $cell->getCellFormat()->getFillFormat();
$image = getPictureFillImage($fillFormat);
if (!isNullJava($image)) {
$displayRow = $rowIndex + 1;
$displayColumn = $columnIndex + 1;
$fileNameBase = $shapeReference->namePart . "_cell_" . $displayRow . "_" . $displayColumn;
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
}
}
}
}
}
} finally {
$presentation->dispose();
}
從圖表形狀提取影像
Chart 為形狀。以下範例從圖表區域的圖片填充中提取影像。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "chart-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, true);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.Chart"))) {
$chart = $shapeReference->shape;
$fillFormat = $chart->getFillFormat();
$image = getPictureFillImage($fillFormat);
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_chart_area";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
}
}
}
} finally {
$presentation->dispose();
}
從 SmartArt 形狀提取影像
SmartArt 物件是形狀。依據 SmartArt 版面配置,影像可能儲存在節點項目的項目符號填充中,或儲存在節點形狀的填充格式中。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "smartart-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, true);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.SmartArt"))) {
$smartArt = $shapeReference->shape;
$allNodes = $smartArt->getAllNodes();
$nodeCount = java_values($allNodes->size());
for ($nodeIndex = 0; $nodeIndex < $nodeCount; $nodeIndex++) {
$node = $allNodes->get_Item($nodeIndex);
$bulletFillFormat = $node->getBulletFillFormat();
$bulletImage = getPictureFillImage($bulletFillFormat);
if (!isNullJava($bulletImage)) {
$displayNode = $nodeIndex + 1;
$fileNameBase = $shapeReference->namePart . "_smartart_node_" . $displayNode . "_bullet";
saveOriginalImage($bulletImage, $outputDirectory, $fileNameBase, $savedImageHashes);
}
$nodeShapes = $node->getShapes();
$nodeShapeCount = java_values($nodeShapes->size());
for ($nodeShapeIndex = 0; $nodeShapeIndex < $nodeShapeCount; $nodeShapeIndex++) {
$nodeShape = $nodeShapes->get_Item($nodeShapeIndex);
$fillFormat = $nodeShape->getFillFormat();
$image = getPictureFillImage($fillFormat);
if (!isNullJava($image)) {
$displayNode = $nodeIndex + 1;
$displayNodeShape = $nodeShapeIndex + 1;
$fileNameBase = $shapeReference->namePart . "_smartart_node_" . $displayNode . "_shape_" . $displayNodeShape;
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
}
}
}
}
}
} finally {
$presentation->dispose();
}
包含群組形狀內的影像
群組形狀包含自己的形狀集合。共享的 enumerateShapes 輔助方法有一個 includeGroupedShapes 選項。若要檢查位於 GroupShape 物件內的形狀,請將其設為 true。以下範例從圖片框、圖片填充形狀、OLE 物件預覽、影片框縮圖以及音訊框縮圖中提取影像。若要同時包含表格、圖表、SmartArt 與摘要縮放的影像,請重新使用前述章節的專屬提取邏輯,同時保留相同的遞迴形狀遍歷方式。
use aspose\slides\Presentation;
$inputPath = "sample.pptx";
$outputDirectory = getcwd() . DIRECTORY_SEPARATOR . "all-shape-images";
if (!is_dir($outputDirectory)) {
mkdir($outputDirectory, 0777, true);
}
$savedImageHashes = [];
$presentation = new Presentation($inputPath);
try {
$slideCount = java_values($presentation->getSlides()->size());
for ($slideIndex = 0; $slideIndex < $slideCount; $slideIndex++) {
$slide = $presentation->getSlides()->get_Item($slideIndex);
$slideNumber = java_values($slide->getSlideNumber());
$slidePrefix = "slide_" . $slideNumber;
$shapes = $slide->getShapes();
$shapeReferences = enumerateShapes($shapes, $slidePrefix, true);
foreach ($shapeReferences as $shapeReference) {
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.OleObjectFrame"))) {
$oleObjectFrame = $shapeReference->shape;
$image = $oleObjectFrame->getSubstitutePictureFormat()->getPicture()->getImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_ole_preview";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
continue;
}
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.VideoFrame"))) {
$videoFrame = $shapeReference->shape;
$image = $videoFrame->getPictureFormat()->getPicture()->getImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_video_preview";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
continue;
}
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.AudioFrame"))) {
$audioFrame = $shapeReference->shape;
$image = $audioFrame->getPictureFormat()->getPicture()->getImage();
if (!isNullJava($image)) {
$fileNameBase = $shapeReference->namePart . "_audio_preview";
saveOriginalImage($image, $outputDirectory, $fileNameBase, $savedImageHashes);
}
continue;
}
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.PictureFrame"))) {
$pictureFrame = $shapeReference->shape;
$image = $pictureFrame->getPictureFormat()->getPicture()->getImage();
saveOriginalImage($image, $outputDirectory, $shapeReference->namePart, $savedImageHashes);
continue;
}
if (java_instanceof($shapeReference->shape, new JavaClass("com.aspose.slides.AutoShape"))) {
$autoShape = $shapeReference->shape;
$fillFormat = $autoShape->getFillFormat();
$image = getPictureFillImage($fillFormat);
if (!isNullJava($image)) {
saveOriginalImage($image, $outputDirectory, $shapeReference->namePart, $savedImageHashes);
}
}
}
}
} finally {
$presentation->dispose();
}
邊緣情況與實務說明
- 重複影像:多個形狀可能參照同一張影像,或是不同的影像卻有相同的位元組。若希望每個唯一影像只產生一個輸出檔,請在寫入檔案前使用
getBinaryData()取得的 PPImage 資料計算 SHA-256 雜湊。 - 原始資料與轉換輸出:儲存 PPImage 從
getBinaryData()取得的資料,可保留嵌入的 JPEG、PNG、GIF、SVG、EMF 或 WMF 資料。使用getImage()的結果適用於需要統一輸出格式的情況。 - 不支援的填充類型:實心、漸層、圖案及無填充的形狀不含圖片填充。讀取
getPictureFillFormat()前請先檢查 FillType。 - 群組形狀:頂層投影片形狀集合不會自動展開群組。若群組內容很重要,請透過
getShapes()递归檢查 GroupShape 內部。 - OLE 物件預覽:OleObjectFrame 可能透過
getSubstitutePictureFormat()提供預覽影像,但該影像僅為投影片預覽,並非 OLE 物件內嵌的檔案。 - 影片框縮圖:VideoFrame 可能透過
getPictureFormat()提供預覽影像,該影像僅為投影片上顯示的海報,並非從影片串流中解碼的影格。 - 音訊框縮圖:AudioFrame 可能透過
getPictureFormat()提供圖示或縮圖;它不代表嵌入的音訊資料。 - 縮放影像:投影片縮放、章節縮放與摘要縮放形狀可能使用自訂的 PPImage 物件,透過
getZoomImage()取得。 - 巢狀形狀模型:表格、圖表與 SmartArt 物件皆實作 Shape,但其影像常儲存在巢狀的表格儲存格、圖表元素或 SmartArt 節點的格式物件中。
- 裁剪或變形的圖片:取得 PPImage 只會得到儲存的影像資源,並不會套用形狀所做的裁剪、透明度、重新著色、旋轉或其他視覺效果。
常見問題
我可以在不裁剪、套用效果或形狀變換的情況下提取原始影像嗎?
是。存取 PPImage 物件,並將 getBinaryData() 的資料寫入磁碟,即可保留投影片中儲存的原始編碼影像,而非投影片上呈現的效果。
我可以將所有提取的影像匯出為 PNG 嗎?
是。使用 PPImage 及其 getImage() 方法,然後呼叫 save() 並指定 ImageFormat 為 PNG。此方式會將輸出轉換為 PNG,可能不會保留原始檔案類型或向量資料。
我要如何避免多次儲存相同的影像?
使用 getBinaryData() 取得的 PPImage 資料計算雜湊,將雜湊值存入集合。若新影像的雜湊已存在,則跳過或改為記錄對已存在輸出檔的另一個參考。
為什麼某些形狀不會產生影像?
圖片框、圖片填充形狀、OLE 物件框、媒體框、縮放框、表格、圖表與 SmartArt 物件都可能參照影像。但某些形狀的影像是透過巢狀的格式物件暴露,僅檢查 getPictureFormat() 或形狀的 getFillFormat() 並不足以捕捉所有情況。
我可以提取影片框顯示的縮圖嗎?
是。使用 VideoFrame 並讀取 getPictureFormat()->getPicture()->getImage(),即可提取隨影片框儲存的海報影像,而非從影片檔案中產生的影格。
我該如何判斷哪些形狀使用投影片影像集合中的特定影像?
Aspose.Slides 不會從 PPImage 反向追蹤至形狀。於遍歷過程中建立映射:每當發現影像參考時,記錄投影片編號、形狀路徑以及影像雜湊或集合項目。
我可以提取嵌入於 OLE 物件內的影像,例如附加的文件嗎?
您可以從 OleObjectFrame 提取該物件的投影片預覽影像。但此預覽影像並非嵌入的文件本身。若要從嵌入的檔案中提取影像,需要先提取 OLE 資料,然後使用相應檔案類型的工具進行檢查。