LoginSignup
1
1

More than 3 years have passed since last update.

Google Apps Script を使ってアルファチャネル付き PNG データを作成したい

Last updated at Posted at 2021-04-20

概要

この投稿では、Google Apps Script を使ったアルファチャネル付き PNG データの作成について紹介させていただきます。

アルファチャネル付き PNG データとは、背景が透明になっているような画像データを意味します。(デモのセクションで確認できます。) これまで Google Apps Script でアルファチャネル付き PNG データを作成するための方法について探していましたが、残念ながら見つかりませんでした。最近になって、ようやくその方法を見つけることができましたので、こちらでも紹介させていただきます。この方法の key factors は次の通りです。

  1. Google Apps Script のメソッドや Google APIs では不可能なことを実現するために Google Apps Script ライブラリ DocsServiceApp を作成したこと。
  • このライブラリのcreateNewSlidesWithPageSizeメソッドでは、ページサイズを指定して Google Slides を作成することができます。これは現行の Google Apps Script のメソッドや Google APIs ではできません。
  1. Google Slides を PNG データとしてエクスポートすることができることが分かったこと。
  • Drive API のexportFormatsを見ると、Google Slides (application/vnd.google-apps.presentation)は、次の 4 通りの mimeType として出力することができることが分かっています。
    • application/vnd.oasis.opendocument.presentation
    • application/pdf
    • application/vnd.openxmlformats-officedocument.presentationml.presentation
    • text/plain
  • 上記の通り、Google Slides は PNG(image/png)として出力することはできない仕様でしたが、これが PNG として出力できることを発見しました。さらに、出力された PNG データはアルファチャネルを含んでいることもわかりました。
  • 追加情報として、svg を指定すると、svg としても出力することが可能であることを確認しました。これもまた他で応用することができそうに思います。
  1. 手動で Google Slides のスライドの背景を透明にするか、SlidesApp.openById(presentationId).getSlides()[0].getBackground().setTransparent()のスクリプトを使ってスライドの背景を透明にした状態で、PNG として出力すると、透明の背景を維持した状態で PNG データを作成できることが分かったこと。

上記の 3 つの key factors によって、Google Apps Script を使ったアルファチャネル付き PNG データの作成が可能になりました。

デモ

このデモンストレーションでは、Google Apps Script で作成したアルファチャネル付きの画像を Google Spreadsheet へ挿入しています。

fig1.gif

流れ

この方法の流れは次の通りです。

  1. Google Slides を指定したサイズで作成する。
  • これはテンポラルファイルとして使用します。
  1. Google Slides の背景を透明にします。

  2. Google Slides へ Shape や Text などを挿入します。

  • この場合、最初の 1 ページ目を使用します。
  1. PNG の mimeType で Export のエンドポイントを使ってデータを出力します。

  2. テンポラルファイルを削除します。

使用方法

ここでは、サンプルとしてスクリプトを Google Spreadsheet の Container-bound script で使用します。そのため、Google Spreadsheet を作成し、スクリプトエディタを開き、下記を実行してください。

1. Google Apps Script library

Google Apps Script library DocsServiceAppをインストールします。ライブラリのプロジェクトキーは、108j6x_ZX544wEhGkgddFYM6Ie09edDqXaFwnW3RVFQCLHw_mEueqUHTWです。リポジトリは、こちらです。

2. Drive API

Advanced Google Services で Drive API を有効にします。

3. サンプルスクリプト

スクリプトエディタへ下記のスクリプトをコピーペーストして保存して下さい。

function myFunction() {
  // 1. Create new Google Slides with the custom page size. This is used as a temporal file.
  const width = 200;
  const height = 200;
  const object = {
    title: "temp",
    width: { unit: "pixel", size: width },
    height: { unit: "pixel", size: height },
  };
  const presentationId = DocsServiceApp.createNewSlidesWithPageSize(object);

  // 2. Create a sample shape to Google Slides.
  const s = SlidesApp.openById(presentationId);
  const slide = s.getSlides()[0];
  slide.getBackground().setTransparent();
  const obj = slide
    .insertShape(SlidesApp.ShapeType.HEART)
    .setWidth(130)
    .setHeight(130)
    .alignOnPage(SlidesApp.AlignmentPosition.CENTER);
  obj.getFill().setTransparent();
  obj.getBorder().setWeight(10).getLineFill().setSolidFill("#ff0000");
  s.saveAndClose();

  // 3. Export Google Slides as a PNG data with the alpha channel.
  const url = `https://docs.google.com/feeds/download/presentations/Export?id=${presentationId}&exportFormat=png`;
  const blob = UrlFetchApp.fetch(url, {
    headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() },
  }).getBlob();

  // 4. Put the created image to Google Spreadsheet.
  const spreadsheetId = "###"; // Please set the Spreadsheet ID.
  const sheetName = "Sheet1";
  const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(
    sheetName
  );
  sheet.insertImage(blob, 2, 2);

  // 5. Remove the Google Slides.
  DriveApp.getFileById(presentationId).setTrashed(true);
}

このスクリプトを実行すると、上記のデモンストレーションのような結果を得ることができます。

例えば、今の場合、下記のスクリプトを使用して既存の Google Slides も使用可能です。

function myFunction2() {
  const presentationId = "###"; // Please set the Google Slides ID.
  const spreadsheetId = "###"; // Please set the Spreadsheet ID.
  const sheetName = "Sheet1";

  const s = SlidesApp.openById(presentationId);
  const slide = s.getSlides()[0];
  slide.getBackground().setTransparent();
  s.saveAndClose();
  const url = `https://docs.google.com/feeds/download/presentations/Export?id=${presentationId}&exportFormat=png`;
  const blob = UrlFetchApp.fetch(url, {
    headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() },
  }).getBlob();

  const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(
    sheetName
  );
  sheet.insertImage(blob, 2, 2);
}

英語版はこちらです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1