概要
この投稿では、Google Apps Script を使ったアルファチャネル付き PNG データの作成について紹介させていただきます。
アルファチャネル付き PNG データとは、背景が透明になっているような画像データを意味します。(デモのセクションで確認できます。) これまで Google Apps Script でアルファチャネル付き PNG データを作成するための方法について探していましたが、残念ながら見つかりませんでした。最近になって、ようやくその方法を見つけることができましたので、こちらでも紹介させていただきます。この方法の key factors は次の通りです。
-
Google Apps Script のメソッドや Google APIs では不可能なことを実現するために Google Apps Script ライブラリ DocsServiceApp を作成したこと。
- このライブラリの
createNewSlidesWithPageSize
メソッドでは、ページサイズを指定して Google Slides を作成することができます。これは現行の Google Apps Script のメソッドや Google APIs ではできません。
- このライブラリの
-
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 としても出力することが可能であることを確認しました。これもまた他で応用することができそうに思います。
- Drive API の
-
手動で Google Slides のスライドの背景を透明にするか、
SlidesApp.openById(presentationId).getSlides()[0].getBackground().setTransparent()
のスクリプトを使ってスライドの背景を透明にした状態で、PNG として出力すると、透明の背景を維持した状態で PNG データを作成できることが分かったこと。
上記の 3 つの key factors によって、Google Apps Script を使ったアルファチャネル付き PNG データの作成が可能になりました。
デモ
このデモンストレーションでは、Google Apps Script で作成したアルファチャネル付きの画像を Google Spreadsheet へ挿入しています。
流れ
この方法の流れは次の通りです。
-
Google Slides を指定したサイズで作成する。
- これはテンポラルファイルとして使用します。
-
Google Slides の背景を透明にします。
-
Google Slides へ Shape や Text などを挿入します。
- この場合、最初の 1 ページ目を使用します。
-
PNG の mimeType で Export のエンドポイントを使ってデータを出力します。
-
テンポラルファイルを削除します。
使用方法
ここでは、サンプルとしてスクリプトを 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);
}
英語版はこちらです。