PHPでプレゼンテーションの BLOB を管理し、メモリ使用を効率化する

概要

Aspose.Slides は、プレゼンテーション内の大きなバイナリ データ(画像、音声、動画、プレゼンテーション ファイル)を扱う際のメモリ使用量を削減するために、BLOB ベースの処理を提供します。

本記事では、BLOB ベースの処理を使用してプレゼンテーションに大容量メディアを追加する方法、プレゼンテーションから大容量メディアをエクスポートする方法、そして大規模なプレゼンテーションをより効率的にロードする方法を示します。また、処理中に一時ファイルを使用する方法と、保存先フォルダーを変更する方法についても説明します。

BLOB について

BLOBBinary Large Object)は、通常、バイナリ形式で保存される大きな項目(写真、プレゼンテーション、ドキュメント、メディア)を指します。

Aspose.Slides for PHP via Java は、巨大ファイルを扱う際のメモリ使用量を削減する方法として、オブジェクトに BLOB を使用できるようにします。

BLOB を使用してメモリ使用量を削減する

BLOB を使用して大きなファイルをプレゼンテーションに追加する

Aspose.Slides for Java は、メモリ使用量を削減するために BLOB を利用したプロセスで大きなファイル(この例では大容量ビデオ ファイル)を追加できるようにします。

この Java のサンプルは、BLOB プロセスを介して大容量ビデオ ファイルをプレゼンテーションに追加する方法を示しています:

  $pathToVeryLargeVideo = "veryLargeVideo.avi";
  # ビデオが追加される新しいプレゼンテーションを作成します
  $pres = new Presentation();
  try {
    $fileStream = new Java("java.io.FileInputStream", $pathToVeryLargeVideo);
    try {
      # ビデオをプレゼンテーションに追加します - KeepLocked 動作を選択したのは、
      # 「veryLargeVideo.avi」ファイルにアクセスするつもりがないためです。
      $video = $pres->getVideos()->addVideo($fileStream, LoadingStreamBehavior->KeepLocked);
      $pres->getSlides()->get_Item(0)->getShapes()->addVideoFrame(0, 0, 480, 270, $video);
      # プレゼンテーションを保存します。大きなプレゼンテーションが出力される間、メモリ消費は
      # pres オブジェクトのライフサイクル全体で低く保たれます
      $pres->save("presentationWithLargeVideo.pptx", SaveFormat::Pptx);
    } finally {
      if (!java_is_null($fileStream)) {
        $fileStream->close();
      }
    }
  } catch (JavaException $e) {
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

BLOB を使用してプレゼンテーションから大きなファイルをエクスポートする

Aspose.Slides for PHP via Java は、プレゼンテーションから BLOB を利用したプロセスで大容量ファイル(この例では音声またはビデオ ファイル)をエクスポートできます。たとえば、プレゼンテーションから大容量メディア ファイルを抽出したいが、ファイルをコンピューターのメモリにロードしたくない場合があります。BLOB プロセスを介してエクスポートすることで、メモリ使用量を低く抑えることができます。

このコードは、上記の操作を実演しています:

  $hugePresentationWithAudiosAndVideosFile = "LargeVideoFileTest.pptx";
  $loadOptions = new LoadOptions();
  # ソース ファイルをロックし、メモリにロードしません
  $loadOptions->getBlobManagementOptions()->setPresentationLockingBehavior(PresentationLockingBehavior->KeepLocked);
  # Presentation のインスタンスを作成し、"hugePresentationWithAudiosAndVideos.pptx" ファイルをロックします。
  $pres = new Presentation($hugePresentationWithAudiosAndVideosFile, $loadOptions);
  try {
    # 各ビデオをファイルに保存します。メモリ使用量が高くなるのを防ぐために、バッファが必要です
    # プレゼンテーションのビデオ ストリームから新しく作成したビデオ ファイル用のストリームへデータを転送するために使用します。
    $Array = new JavaClass("java.lang.reflect.Array");
    $Byte = new JavaClass("java.lang.Byte");
    $buffer = $Array->newInstance($Byte, 8 * 1024);
    # ビデオを走査します
    for($index = 0; $index < java_values($pres->getVideos()->size()) ; $index++) {
      $video = $pres->getVideos()->get_Item($index);
      # プレゼンテーションのビデオ ストリームを開きます。意図的にプロパティへのアクセスを避けたことにご注意ください
      # video.BinaryData のようなプロパティは、完全なビデオを含むバイト配列を返すため、
      # メモリにバイトをロードします。video.GetStream を使用すれば、Stream が返され、かつ
      # ビデオ全体をメモリにロードする必要はありません
      $presVideoStream = $video->getStream();
      try {
        $outputFileStream = new Java("java.io.FileOutputStream", "video" . $index . ".avi");
        try {
          $bytesRead;
          while ($bytesRead = $presVideoStream->read($buffer, 0, java_values($Array->getLength($buffer))) > 0) {
            $outputFileStream->write($buffer, 0, $bytesRead);
          } 
        } finally {
          $outputFileStream->close();
        }
      } finally {
        $presVideoStream->close();
      }
      # ビデオやプレゼンテーションのサイズに関係なく、メモリ消費は低く抑えられます
    }
    # 必要に応じて、オーディオ ファイルにも同じ手順を適用できます
  } catch (JavaException $e) {
  } finally {
    $pres->dispose();
  }

画像を BLOB としてプレゼンテーションに追加する

ImageCollection クラスのメソッドを使用すると、ストリームとして大きな画像を追加し、BLOB として扱うことができます。

この PHP のサンプルは、BLOB プロセスを介して大容量画像を追加する方法を示しています:

  $pathToLargeImage = "large_image.jpg";
  # 画像が追加される新しいプレゼンテーションを作成します。
  $pres = new Presentation();
  try {
    $fileStream = new Java("java.io.FileInputStream", $pathToLargeImage);
    try {
      # 画像をプレゼンテーションに追加します - KeepLocked 動作を選択したのは、
      # 「largeImage.png」ファイルにアクセスするつもりがないためです。
      $img = $pres->getImages()->addImage($fileStream, LoadingStreamBehavior->KeepLocked);
      $pres->getSlides()->get_Item(0)->getShapes()->addPictureFrame(ShapeType::Rectangle, 0, 0, 300, 200, $img);
      # プレゼンテーションを保存します。大きなプレゼンテーションが出力される間、メモリ消費は
      # pres オブジェクトのライフサイクル全体で低く保たれます
      $pres->save("presentationWithLargeImage.pptx", SaveFormat::Pptx);
    } finally {
      if (!java_is_null($fileStream)) {
        $fileStream->close();
      }
    }
  } catch (JavaException $e) {
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

メモリと大規模プレゼンテーション

通常、大規模なプレゼンテーションをロードするには、多くの一時メモリが必要です。プレゼンテーションの全コンテンツがメモリに読み込まれ、ロード元のファイルは使用されなくなります。

たとえば、1.5 GB のビデオ ファイルを含む大容量 PowerPoint プレゼンテーション(large.pptx)を考えてみましょう。標準的なロード方法は、次の PHP コードで示されています:

  $pres = new Presentation("large.pptx");
  try {
    $pres->save("large.pdf", SaveFormat::Pdf);
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

しかし、この方法では約 1.6 GB の一時メモリが消費されます。

BLOB として大規模プレゼンテーションを読み込む

BLOB を利用したプロセスにより、ほとんどメモリを使用せずに大規模プレゼンテーションをロードできます。この PHP コードは、BLOB プロセスを使用して large.pptx をロードする実装例を示しています:

  $loadOptions = new LoadOptions();
  $loadOptions->getBlobManagementOptions()->setPresentationLockingBehavior(PresentationLockingBehavior->KeepLocked);
  $loadOptions->getBlobManagementOptions()->setTemporaryFilesAllowed(true);
  $pres = new Presentation("large.pptx", $loadOptions);
  try {
    $pres->save("large.pdf", SaveFormat::Pdf);
  } finally {
    if (!java_is_null($pres)) {
      $pres->dispose();
    }
  }

一時ファイルのフォルダーを変更する

BLOB プロセスが使用されると、コンピューターはデフォルトの一時ファイル フォルダーに一時ファイルを作成します。別のフォルダーに一時ファイルを保存したい場合は、setTempFilesRootPath を使用して保存先を変更できます:

  $loadOptions = new LoadOptions();
  $loadOptions->getBlobManagementOptions()->setPresentationLockingBehavior(PresentationLockingBehavior->KeepLocked);
  $loadOptions->getBlobManagementOptions()->setTemporaryFilesAllowed(true);
  $loadOptions->getBlobManagementOptions()->setTempFilesRootPath("temp");

プレゼンテーションオブジェクトを破棄してメモリを解放する

大規模プレゼンテーションを処理する際は、Presentation インスタンスを適切に破棄し、占有していたメモリを解放してください。プレゼンテーションの使用が終了したら dispose() を呼び出して、アンマネージド リソースを解放します。

$presentation = new Presentation("large.pptx");

# ...プレゼンテーションを処理します...
$presentation->save("large.pdf", SaveFormat::Pdf);

# リソースを明示的に解放します。
$presentation->dispose();

FAQ

Aspose.Slides のプレゼンテーションで BLOB として扱われ、BLOB オプションで制御されるデータは何ですか?

画像、音声、動画などの大型バイナリ オブジェクトが BLOB として扱われます。プレゼンテーション全体のファイルも、ロードまたは保存時に BLOB 処理の対象となります。これらのオブジェクトは、メモリ使用量を管理し、必要に応じて一時ファイルにスピルできるようにする BLOB ポリシーによって制御されます。

プレゼンテーションのロード時に BLOB 処理ルールを設定する場所はどこですか?

LoadOptionsBlobManagementOptions を組み合わせて使用します。ここで BLOB のメモリ上限を設定したり、一時ファイルの使用可否を指定したり、テンポラリ ファイルのルート パスを選択したり、ソース ロックの動作を選択できます。

BLOB 設定はパフォーマンスに影響しますか?速度とメモリのバランスはどう取ればよいですか?

はい。BLOB をメモリに保持すると速度は最大化されますが RAM 使用量が増加します。メモリ上限を下げると、処理の一部が一時ファイルに転嫁され、RAM は削減されますが I/O が増加します。ワークロードと環境に合わせて最適なバランスを取るには、setMaxBlobsBytesInMemory メソッドを使用してください。

極めて大容量のプレゼンテーション(数ギガバイト規模)を開く際に BLOB オプションは役立ちますか?

はい。BlobManagementOptions はそのようなシナリオ向けに設計されています。一時ファイルを有効化し、ソース ロックを使用することで、ピーク時の RAM 使用量を大幅に削減し、非常に大きなデッキの処理を安定させることができます。

ディスク ファイルではなくストリームからロードする場合にも BLOB ポリシーを使用できますか?

はい。ストリームにも同じルールが適用されます。プレゼンテーション インスタンスは、選択したロック モードに応じて入力ストリームを所有およびロックでき、許可されている場合は一時ファイルが使用されるため、処理中のメモリ使用量を予測可能に保てます。