Use Cases

Claude Codeで画像処理を自動化する方法

Claude Codeを使ってSharpによる画像リサイズ・変換・最適化を自動化。バッチ処理やWebP変換の実践コード付き。

画像処理の自動化にClaude Codeを活用する

Webアプリでは画像のリサイズ、フォーマット変換、最適化が頻繁に必要です。Claude Codeを使えば、Sharpライブラリを活用した画像処理パイプラインを効率的に構築できます。

基本:画像リサイズと最適化

> Sharpを使って画像のリサイズ・WebP変換・メタデータ削除を行うユーティリティを作って。
import sharp from "sharp";
import path from "path";

interface ProcessOptions {
  width?: number;
  height?: number;
  quality?: number;
  format?: "webp" | "avif" | "jpeg" | "png";
}

export async function processImage(
  inputPath: string,
  outputDir: string,
  options: ProcessOptions = {}
) {
  const { width = 1200, height, quality = 80, format = "webp" } = options;
  const filename = path.basename(inputPath, path.extname(inputPath));
  const outputPath = path.join(outputDir, `${filename}.${format}`);

  let pipeline = sharp(inputPath)
    .resize(width, height, {
      fit: "inside",
      withoutEnlargement: true,
    })
    .removeMetadata();

  switch (format) {
    case "webp":
      pipeline = pipeline.webp({ quality });
      break;
    case "avif":
      pipeline = pipeline.avif({ quality });
      break;
    case "jpeg":
      pipeline = pipeline.jpeg({ quality, mozjpeg: true });
      break;
    case "png":
      pipeline = pipeline.png({ compressionLevel: 9 });
      break;
  }

  const info = await pipeline.toFile(outputPath);

  return {
    outputPath,
    width: info.width,
    height: info.height,
    size: info.size,
  };
}

レスポンシブ画像の一括生成

複数サイズの画像を一度に生成して、<picture> 要素やsrcsetに対応させます。

interface ResponsiveSize {
  width: number;
  suffix: string;
}

const RESPONSIVE_SIZES: ResponsiveSize[] = [
  { width: 320, suffix: "sm" },
  { width: 640, suffix: "md" },
  { width: 1024, suffix: "lg" },
  { width: 1920, suffix: "xl" },
];

export async function generateResponsiveImages(
  inputPath: string,
  outputDir: string
) {
  const filename = path.basename(inputPath, path.extname(inputPath));
  const results = [];

  for (const size of RESPONSIVE_SIZES) {
    const outputPath = path.join(outputDir, `${filename}-${size.suffix}.webp`);

    const info = await sharp(inputPath)
      .resize(size.width, null, {
        fit: "inside",
        withoutEnlargement: true,
      })
      .webp({ quality: 80 })
      .toFile(outputPath);

    results.push({
      path: outputPath,
      width: info.width,
      height: info.height,
      size: info.size,
    });
  }

  return results;
}

バッチ処理スクリプト

フォルダ内の画像を一括処理するCLIスクリプトです。

import fs from "fs/promises";
import path from "path";
import { processImage } from "./image-processor";

async function batchProcess(inputDir: string, outputDir: string) {
  await fs.mkdir(outputDir, { recursive: true });

  const files = await fs.readdir(inputDir);
  const imageFiles = files.filter((f) =>
    /\.(jpg|jpeg|png|gif|bmp|tiff)$/i.test(f)
  );

  console.log(`${imageFiles.length}件の画像を処理します...`);

  const results = await Promise.allSettled(
    imageFiles.map(async (file) => {
      const inputPath = path.join(inputDir, file);
      const result = await processImage(inputPath, outputDir, {
        width: 1200,
        quality: 80,
        format: "webp",
      });

      const originalSize = (await fs.stat(inputPath)).size;
      const reduction = ((1 - result.size / originalSize) * 100).toFixed(1);
      console.log(`  ${file} → ${path.basename(result.outputPath)} (${reduction}% 削減)`);
      return result;
    })
  );

  const succeeded = results.filter((r) => r.status === "fulfilled").length;
  const failed = results.filter((r) => r.status === "rejected").length;
  console.log(`完了: 成功 ${succeeded}件, 失敗 ${failed}件`);
}

// 実行
batchProcess("./images/raw", "./images/optimized");

OGP画像の動的生成

ブログ記事のOGP画像を自動生成する機能も作れます。

import sharp from "sharp";

export async function generateOgImage(title: string, outputPath: string) {
  const width = 1200;
  const height = 630;

  const svgText = `
    <svg width="${width}" height="${height}">
      <rect width="100%" height="100%" fill="#1e293b"/>
      <text x="50%" y="45%" text-anchor="middle" fill="white"
        font-size="48" font-family="sans-serif" font-weight="bold">
        ${escapeXml(title.length > 30 ? title.slice(0, 30) + "..." : title)}
      </text>
      <text x="50%" y="65%" text-anchor="middle" fill="#94a3b8"
        font-size="24" font-family="sans-serif">
        ClaudeCodeLab
      </text>
    </svg>
  `;

  await sharp(Buffer.from(svgText))
    .resize(width, height)
    .png()
    .toFile(outputPath);
}

function escapeXml(str: string) {
  return str.replace(/[<>&'"]/g, (c) =>
    ({ "<": "&lt;", ">": "&gt;", "&": "&amp;", "'": "&apos;", '"': "&quot;" })[c] || c
  );
}

画像処理と組み合わせて使えるPDF生成についてはPDF生成機能をご覧ください。Claude Codeの基本的な使い方は入門ガイドを参照してください。

まとめ

Claude Codeを使えば、画像リサイズ、フォーマット変換、レスポンシブ対応、OGP生成まで、画像処理に関する機能を短時間で実装できます。要件を自然言語で伝えるだけで、Sharpの複雑なAPIを適切に使ったコードが得られます。

詳しくはClaude Code公式ドキュメントをご覧ください。

#Claude Code #画像処理 #Sharp #最適化 #自動化