[GAS 外部API]GASでPDFを画像に変換しよう

GASでPDFを画像にしようGAS

どうも。Kenny(tsujikenzo)です。 今日は単発で、 「GASでPDFを画像に変換しよう」 をお送りします。シリーズの続きみたいなものですね。

前回のおさらい

前回のシリーズでは、GASでPDFを分割・結合しました。

今回は、GASでPDFを画像に変換しよう、をお届けします。

画像とは

Gemini APIで画像認識をしてみよう」のブログで、Geminiは、以下の画像形式をサポートしていることをお伝えしました。

  • PNG – image/png
  • JPEG – image/jpeg
  • WEBP – image/webp
  • HEIC – image/heic
  • HEIF – image/heif

なので、PDFをいずれかの画像形成に変換しておけば、画像認識まで自動化できそうです。

GASによる画像化

しかしながらGASでは、以下の理由により、PDFを画像化できません。

  1. PDF→画像(JPG/PNG)変換するメソッドがない
  2. 前述したPDF処理用のライブラリ(pdf-lib)には、画像化のメソッド(関数含む)がない
  3. Pythonのpdf2imageには、convert_from_path() や convert_from_bytes()があって可能
  4. Google DriveのgetThumbnail()メソッドは低解像度のプレビュー画像(128 x 128 px)を取得する
  5. Google ドキュメントやスライドにPDFを挿入したとしても画像としてダウンロードはできない

わたし(凡人)の頭では、万策尽きまして、今回はPDFを画像に変換するサービスを使うことにしました。

PDFを画像に変換するサービス

みなさんも、インターネット上で、PDFを分割したり結合したり画像に変換するサービスを利用したことがあると思います。

老舗オンラインPDF処理サービスの1つI LOVE PDFなどは、有名ですね。 

他にも、数多くのサービスがありますが、APIを公開しているサービスもあります。 

この中で、わたしのような初学者でも扱えるものがないか、毎夜吐いたり泣いたりしながら、たどり着いたサービスが、PDF.coです。

1カ月は無料で使えて、大量の画像化処理をしてくれて月額1,500円なら投資することにしました。そのうちGeminiがPDFにも対応したらサブスク解除します。

API to Extract PDF, Edit & Convert PDF, Create PDF | PDF.co
PDF.co Web API for extracting, editing, converting, merging, and splitting PDF documents. Save time with our powerful tools.

今回は、こちらのAPIを使って、PDFを画像に変換してみましょう。

APIの公式リファレンスはこちらです。

API — pdf.co documentation
PDF.co Developer documentation.

下準備

いくつか、下準備をしましょう。

フォルダ構成とフォルダID

前回までのブログを参考にして、「分割済み」フォルダの中に、2つのフォルダを追加しておきます。

  • 01_画像化済み
  • 02_画像化処理済み元ファイル

このような構成にしておきましょう。 

プロパティストアにも、IDを格納しておきます。

const PDF_TO_IMAGE_FOLDER_ID = "あなたのフォルダID";  // 01_画像化済みフォルダ
properties.setProperty("PDF_TO_IMAGE_FOLDER_ID", PDF_TO_IMAGE_FOLDER_ID);

const PROCESSED_IMAGECASH_FOLDER_ID = "あなたのフォルダID"; // 02_画像化処理済み元ファイル
properties.setProperty("PROCESSED_IMAGECASH_FOLDER_ID", PROCESSED_IMAGECASH_FOLDER_ID);

アカウントの準備とAPI Key

PDF.coでアカウントを作成します。(この辺の操作は、割愛します) 

ログインすると、ダッシュボードが表示されます。そして、目の前に思いっきりYour API Keyが表示されています。

コピーしてメモしておきましょう。 

API Keyもプロパティストアに格納しておきます。

const PDFCO_API_KEY = "あなたのAPI KEY";
properties.setProperty("PDFCO_API_KEY", PDFCO_API_KEY);

メソッドとエンドポイントの確認

PDF.coのPDF to Imageクラスには、画像タイプごとに、4つのメソッドがあります。

  • /pdf/convert/to/jpg
  • /pdf/convert/to/png
  • /pdf/convert/to/webp
  • /pdf/convert/to/tiff

今回の目的はOCRなので、pngにします。

エンドポイントは、https://api.pdf.co/v1/pdf/convert/to/png です。

全体的な流れ(要件定義)

前回の、PDFの分割や結合とほぼ同じです。

  1. 「PDF分割機」の「分割済み」フォルダにPDFファイルがあるか確認する
  2. あれば、ファイルIDを取得して配列に格納する
  3. 各PDFファイルをエンドポイントにリクエスト送信する
  4. 画像化されたファイルをダウンロードする
  5. for文で回す
  6. 元のPDFファイルは「処理済み」フォルダに移動する
  7. 1.を時限トリガーでぶん回す

今回も、要件定義をAIにぶっこみます。

できあがったコード

できあがったコードがこちらです。解説は後にします。とてもシンプルなリクエストになっています。

/**
 * 📄PDF画像変換機
 * 指定フォルダ内のPDF(1ページに分割済み)を、画像化してフォルダに保存する。
 * 元のPDFファイルは処理済みフォルダへ移動する。
 */
function convertPdfToImageByPDFCO() {

//ファルダIDなどを取得しておく
 const properties = PropertiesService.getScriptProperties();
 const API_TOKEN = properties.getProperty("PDFCO_API_KEY");
 const splitFolderId = properties.getProperty("SPLIT_FOLDER_ID");
 const pdfToImageFolderId = properties.getProperty("PDF_TO_IMAGE_FOLDER_ID");
 const tempFolderId = properties.getProperty("PROCESSED_IMAGECASH_FOLDER_ID"); // 一時処理フォルダ

//API Keyが無かったときのガード節
 if (!API_TOKEN) {
   console.error("❌ API トークンが取得できませんでした。");
   return;
 }

//すべてのPDFを取得する
 const pdfFolder = DriveApp.getFolderById(splitFolderId);
 const pdfFiles = pdfFolder.getFilesByType(MimeType.PDF);

//PDFが無かったときのガード節
 if (!pdfFiles.hasNext()) {
   console.log("📂 フォルダ内に PDF がありません");
   return;
 }

//ファイルがなくなるまでwhile分を回す
 while (pdfFiles.hasNext()) {
   const file = pdfFiles.next();
   const pdfBlob = file.getBlob();
   const fileName = file.getName();
    console.log(`🔄 PDF変換開始: ${fileName}`);
  //一時処理フォルダにPDFを保存し、公開リンクを取得
   const tempFolder = DriveApp.getFolderById(tempFolderId);
   const tempFile = tempFolder.createFile(pdfBlob);
   tempFile.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
   const pdfFileUrl = tempFile.getDownloadUrl();

  //エンドポイントとPayload
   const apiUrl = "https://api.pdf.co/v1/pdf/convert/to/png";

  const headers = {
    "x-api-key": API_TOKEN,
    "Content-Type": "application/json"
  };

  const payload = JSON.stringify({
    url: pdfFileUrl,
    pages: "0",
    outputformat: "png"
  });

  const options = {
    method: "post",
    headers: headers,
    payload: payload,
    muteHttpExceptions: true
  };

  try {
    // API にリクエストを送信
    const response = UrlFetchApp.fetch(apiUrl, options);
    const jsonResponse = JSON.parse(response.getContentText());

    console.log(`📡 API Full Response: ${response.getContentText()}`);

    const imageUrl = jsonResponse.urls ? jsonResponse.urls[0] : null;

    //変換できなかったときのガード節
    if (!imageUrl) {
      console.error(`❌ 画像URLを取得できませんでした: ${fileName}`);
      continue;
    }

    console.log(`✅ 変換完了: ${imageUrl}`);

    //画像をダウンロードし、Google Drive に保存
    const imageResponse = UrlFetchApp.fetch(imageUrl);
    const imageBlob = imageResponse.getBlob()
      .setName(fileName.substring(0, fileName.lastIndexOf(".")) + ".png");

    DriveApp.getFolderById(pdfToImageFolderId).createFile(imageBlob);
    console.log(`📂 画像保存完了: ${fileName.substring(0, fileName.lastIndexOf(".")) + ".png"}`);

    //処理済みPDFをゴミ箱へ移動
    file.setTrashed(true);
    console.log(`📂 処理済みフォルダへ移動完了: ${fileName}`);

    //待機処理(サーバー負荷軽減)
    Utilities.sleep(1000); // 1秒待機

   } catch (e) {
    console.error(`❌ ${fileName} の処理中にエラー: ${e.toString()}`);
   }
 }
}

補足解説

PDF.coのエンドポイントへのリクエストには、PDFファイルの公開リンクをPayloadとして持たせる必要があります。ダウンロードリンクではダメです。

なので、公開リンクを取得するために、一時的にGoogle Driveにファイルを作成しています。

また、公開リンクは、誰でも閲覧権限がないといけないので、DriveAppサービスのメンバーを使って、権限を付与しています。

//一時処理フォルダにPDFを保存し、公開リンクを取得
  const tempFolder = DriveApp.getFolderById(tempFolderId);
  const tempFile = tempFolder.createFile(pdfBlob);

//ファイルに閲覧権限を付与する
  tempFile.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);

  const pdfFileUrl = tempFile.getDownloadUrl();

  //中略

 const payload = JSON.stringify({
  url: pdfFileUrl,
  pages: "0",
  outputformat: "png"
});

実行してみる

まず、画像化するための元ファイルが、フォルダにあることを確認しましょう。(前回分割したPDFでいいと思います。)

convertPdfToImageByPDFCO()を実行します。手で。

画像化済みフォルダに、pngファイルが作成されていればOKです。 

処理済みのファイルも移動して、空っぽになっていればOKです。いかがでしょうか。 

まとめ

以上で、「GASでPDFを画像に変換しよう」をお送りしました。

これで、以下の流れが自動化できました。

  • PDFをGoogle Driveに保存する
  • PDFを単ページに分割する
  • PDFを画像に変換する
  • 画像をGemini APIで画像認識(OCR)する

実際の業務では、OCRした内容をGeminiで要約するところまで活用しています。ブログを書く時間は~ないかなぁ。。。

いろんな用途に使えそうですね。それではまた。

このシリーズの目次

参考にして欲しいシリーズ

タイトルとURLをコピーしました