2026/05/18

PDF圧縮API: APIコール1回でPDFファイルサイズを削減する方法

PDF圧縮PDFサイズ削減PDF APIGhostscript

メールでPDFが弾かれる。ダウンロードリンクがタイムアウトする。ストレージコストが積み上がる。PDFが重すぎる場合、最も手軽な解決策はサイズ圧縮です。APIで処理すれば、追加ライブラリもローカルツールも不要です。

FUNBREW PDFの圧縮エンドポイント(POST /api/pdf/compress)は、FUNBREWサーバー上に保存済みのPDFをGhostscriptで圧縮し、新しいダウンロードURLを返します。POSTリクエスト1回だけです。

このガイドではAPIの仕様、品質プリセットの使い分け、cURL・Node.js・Python・PHPのコード例、そして圧縮率を最大化するための実践的なヒントを解説します。

PDFの生成方法についてはPDF APIクイックスタートを、複数PDFの結合はPDFマージAPIガイドを参照してください。

仕組み

圧縮パイプラインは3ステップです。

  1. アカウント内に存在するfilename(以前のFUNBREW PDF API呼び出しで生成されたファイル)を指定してPOST /api/pdf/compressを呼び出す。
  2. サーバーが選択した-dPDFSETTINGSプリセットでGhostscriptを実行する。
  3. 圧縮後のサイズが元より小さければ圧縮済みファイルを、そうでなければ元ファイルを返す。どちらの場合も有効なダウンロードURLが返ります。

このエンドポイントはSaaSエディションでpdf.feature:compressフィーチャーゲートが有効なプランが必要です。

API仕様

POST /api/pdf/compress
Content-Type: application/json
Authorization: Bearer {APIキー}

リクエストパラメータ

パラメータ 必須 説明
filename string Yes アカウント内の既存PDFのファイル名
quality string No 圧縮プリセット: lowmediumhigh(デフォルト: medium
expiration_hours integer No 圧縮済みファイルの有効期限(時間)(0〜168、デフォルト 24)
max_downloads integer No 有効期限前の最大ダウンロード数(0〜100、デフォルト 10)

品質プリセット

qualityパラメータはGhostscriptの-dPDFSETTINGSフラグに対応します。

Ghostscript設定 代表的な用途
low /screen メール添付・プレビュー — 最大サイズ削減
medium /ebook Web配信・業務文書 — バランス重視(デフォルト)
high /printer 印刷用途 — 品質低下を最小化

成功レスポンス

{
  "success": true,
  "data": {
    "filename": "compressed-abc123.pdf",
    "download_url": "https://pdf.funbrew.cloud/api/pdf/download/compressed-abc123.pdf",
    "original_size": 4194304,
    "compressed_size": 1048576,
    "savings_percent": 75.0,
    "expires_at": "2026-05-19T10:00:00Z"
  }
}

savings_percentoriginal_sizeに対する削減率(%)です。値が0の場合、元ファイルが既に最適化されており変更なしで返ったことを意味します。

エラーレスポンス

ステータス 原因
422 filenameがアカウント内に見つからない、またはファイルの有効期限切れ
422 ストレージ上にファイルが存在しない(削除済み)
500 Ghostscriptの実行失敗

コード例

cURL

デフォルトのmedium品質で圧縮する最小構成:

curl -X POST https://pdf.funbrew.cloud/api/pdf/compress \
  -H "Authorization: Bearer $FUNBREW_PDF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "report-abc123.pdf",
    "quality": "medium"
  }'

low品質・有効期限48時間で圧縮:

curl -X POST https://pdf.funbrew.cloud/api/pdf/compress \
  -H "Authorization: Bearer $FUNBREW_PDF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "report-abc123.pdf",
    "quality": "low",
    "expiration_hours": 48,
    "max_downloads": 5
  }'

Node.js

const fs = require('fs');

async function compressPdf(filename, quality = 'medium') {
  const response = await fetch('https://pdf.funbrew.cloud/api/pdf/compress', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FUNBREW_PDF_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ filename, quality }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Compress APIエラー ${response.status}: ${error.message}`);
  }

  const result = await response.json();
  const { download_url, original_size, compressed_size, savings_percent } = result.data;

  console.log(`元サイズ: ${(original_size / 1024).toFixed(1)} KB`);
  console.log(`圧縮後: ${(compressed_size / 1024).toFixed(1)} KB`);
  console.log(`削減率: ${savings_percent}%`);
  console.log(`ダウンロード: ${download_url}`);

  return result.data;
}

// 生成 → 圧縮の2ステップ例
async function generateAndCompress() {
  // Step 1: PDF生成
  const genResponse = await fetch('https://pdf.funbrew.cloud/api/pdf/generate-from-html', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FUNBREW_PDF_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      html: '<h1>年次レポート</h1><p>2026年度のサマリー...</p>',
      engine: 'quality',
      format: 'A4',
      return_type: 'filename',
    }),
  });

  const genResult = await genResponse.json();
  const filename = genResult.data.filename;

  // Step 2: 圧縮
  const compressed = await compressPdf(filename, 'low');
  return compressed.download_url;
}

generateAndCompress().then(url => console.log('最終URL:', url));

Python

import os
import requests

FUNBREW_API_KEY = os.environ["FUNBREW_PDF_API_KEY"]
BASE_URL = "https://pdf.funbrew.cloud/api/pdf"


def compress_pdf(filename: str, quality: str = "medium") -> dict:
    """FUNBREWに保存済みのPDFを圧縮してメタデータを返す。"""
    response = requests.post(
        f"{BASE_URL}/compress",
        headers={"Authorization": f"Bearer {FUNBREW_API_KEY}"},
        json={"filename": filename, "quality": quality},
        timeout=60,
    )
    response.raise_for_status()
    result = response.json()["data"]

    print(f"元サイズ:   {result['original_size'] / 1024:.1f} KB")
    print(f"圧縮後:     {result['compressed_size'] / 1024:.1f} KB")
    print(f"削減率:     {result['savings_percent']}%")
    return result


def generate_and_compress(html: str, quality: str = "medium") -> str:
    """HTMLからPDFを生成して圧縮し、ダウンロードURLを返す。"""
    # Step 1: PDF生成(filenameを返す)
    gen_response = requests.post(
        f"{BASE_URL}/generate-from-html",
        headers={"Authorization": f"Bearer {FUNBREW_API_KEY}"},
        json={
            "html": html,
            "engine": "quality",
            "format": "A4",
            "return_type": "filename",
        },
        timeout=60,
    )
    gen_response.raise_for_status()
    filename = gen_response.json()["data"]["filename"]

    # Step 2: 圧縮
    result = compress_pdf(filename, quality)
    return result["download_url"]


if __name__ == "__main__":
    html = """
    <html><body>
      <h1>四半期レポート</h1>
      <p>高解像度の画像と詳細なグラフを含むレポートです。</p>
    </body></html>
    """
    url = generate_and_compress(html, quality="low")
    print(f"ダウンロードURL: {url}")

PHP

cURL(フレームワーク不問)

function compressPdf(string $filename, string $quality = 'medium'): array
{
    $ch = curl_init('https://pdf.funbrew.cloud/api/pdf/compress');

    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getenv('FUNBREW_PDF_API_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'filename' => $filename,
            'quality'  => $quality,
        ]),
    ]);

    $body = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        throw new RuntimeException("Compress API returned HTTP $httpCode: $body");
    }

    $result = json_decode($body, true)['data'];
    printf(
        "元サイズ: %.1f KB | 圧縮後: %.1f KB | 削減率: %s%%\n",
        $result['original_size'] / 1024,
        $result['compressed_size'] / 1024,
        $result['savings_percent']
    );

    return $result;
}

// 使用例
$result = compressPdf('report-abc123.pdf', 'low');
echo $result['download_url'];

Laravel(Httpファサード)

use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.funbrew.api_key'))
    ->post('https://pdf.funbrew.cloud/api/pdf/compress', [
        'filename'         => 'report-abc123.pdf',
        'quality'          => 'medium',
        'expiration_hours' => 48,
        'max_downloads'    => 20,
    ]);

if ($response->successful()) {
    $data = $response->json('data');
    logger()->info('PDF圧縮完了', [
        'savings_percent' => $data['savings_percent'],
        'download_url'    => $data['download_url'],
    ]);
}

生成 → 圧縮の2ステップパターン

圧縮エンドポイントが受け付けるのは、FUNBREWアカウントにすでに保存されているファイルのみです。PDF生成エンドポイントでreturn_type: "filename"を指定すると、生成されたPDFはサーバー上に保持されてファイル名がレスポンスに含まれます。そのファイル名を/api/pdf/compressにそのまま渡せます。

POST /api/pdf/generate-from-html  →  { filename: "gen-abc.pdf" }
POST /api/pdf/compress            →  { filename: "compressed-xyz.pdf", savings_percent: 68.3 }

このパターンが有効な場面:

  • レポート生成パイプライン: 複雑なHTMLレポートをqualityエンジンで生成し、メール送信前に圧縮する。
  • 証明書バッチ処理: 証明書を一括生成・圧縮してからPDFを結合する。詳細はPDF証明書自動化ガイドを参照。
  • ストレージ効率化: S3やWasabiへのアーカイブ前に圧縮してストレージコストを削減する。

実践的なヒント

プリセットの選び方

  • low/screen): 画像を72dpiに積極的にダウンサンプル。メール配信やプレビューなど、ファイルサイズ最優先の場面に最適。精細なグラフや小さな文字を含む文書には不向き。
  • medium/ebook): 150dpiにダウンサンプル。WebからのPDFダウンロードやSaaSのドキュメントエクスポートに適した標準設定。
  • high/printer): 300dpiにダウンサンプル。印刷用途や画像の鮮明さが重要な場合に使用する。

圧縮効果が低いケース

スキャン画像のみのPDFや、すでにGhostscriptで処理済みのPDFは、追加の圧縮効果がほとんど得られない場合があります。APIはこれを自動的に処理し、出力が元より大きくなる場合は元のコンテンツをそのまま返します(savings_percent: 0)。

200KB以下の小さなファイルに対して圧縮APIを呼び出しても効果が薄いため、直前のAPIレスポンスのファイルサイズを確認してから判断することをお勧めします。

有効期限とダウンロード制限

デフォルトでは24時間・最大10ダウンロードで期限切れになります。バッチパイプラインでファイルを即時ダウンロードまたは外部ストレージへ転送する場合はこのデフォルトで問題ありません。メールでリンクを送る場合など、長期間有効なリンクが必要な場合はexpiration_hoursを最大168(7日間)に設定してください。

次のステップ

関連リンク

Powered by FUNBREW PDF