深掘り

BMP を JPG、PNG、WebP に変換する実践ガイド

koboshiCo-founder
·4 分で読めます
BMP を JPG、PNG、WebP に変換する実践ガイド
要約

BMP は読み込みは簡単だが容量が大きい。本ガイドでは OS 標準ツール、コマンドライン、そして 5 言語でのコードベースの変換をカバーし、BMP を JPG・PNG・WebP に効率よく変換する方法を解説する。

1920 × 1080 の 24 ビット BMP は約 6 MB になる。同じ画像を品質 90 の JPEG で保存すると、通常 500 KB を下回る。およそ 10 倍の差が、BMP が古いスキャナーや医療ソフト、Windows の内部コンポーネントに今も残っている一方で、ほとんどの場合、他で使う前に変換が必要な理由だ。

BMP の強みは単純さにある。うまく変換するには、その単純さがいつ役に立ち、いつ障害になり、どの出力形式が実際の作業に合うのかを知る必要がある。

BMP がまだ残っている理由

BMP は最小限のヘッダーでピクセルを格納する。ハフマンテーブルも DEFLATE ステートマシンも色度サブサンプリングもない。組み込みシステム、レガシー Windows ツール、「ヘッダーを読んでバイトをコピーする」だけで済む場面では、この単純さが実際の利点になる。

一方で、日常から姿を消したのも同じ欠点によるものだ。

  • 有効な圧縮がない。 非圧縮 BMP は巨大だ。RLE 派生型はあるが、現代のコーデックに勝つことは少ない。
  • 信頼できるアルファチャンネルがない。 32 ビット BMP のアルファバイトはツール間でサポートが不安定だ。
  • ボトムアップの行順。 多くの BMP は画像の下側から上側へ行を格納する。トップダウンを期待する処理には小さな変換ステップが追加される。
  • メタデータエコシステムがない。 古典的ヘッダーは EXIF や ICC プロファイルをサポートせず、アニメーションもない。

アーカイブや互換性用途なら BMP は問題ない。Web、メール、モバイル、ストレージ効率を重視するなら、別の形式に変換した方がいい。

適切な出力形式の選び方

コマンドを実行する前に、まず何を優先するか決めよう。

出力形式用途トレードオフ
JPG写真、プレビュー、画面表示全般非可逆だがファイルサイズが小さい
PNG図形、スクリーンショット、透明が必要なもの可逆だが写真は JPG より大きい
WebP現代の Web、アプリ、帯域が気になる場面JPG/PNG より小さく、ブラウザ対応も広い

文字や図表が入ったスキャンドキュメントを変換するなら、PNG が縁を鮮明に保つ。古い機器からの写真なら JPG か WebP が正解。Web 配信なら、通常 WebP がサイズで勝る。

ブラウザ上で動作する BMP to JPGBMP to PNGBMP to WebP コンバーターは、これら 3 つのケースをローカルで処理する——ファイルはユーザーのデバイスから出ない。

Windows で変換する

ペイント

  1. BMP をペイントで開く。
  2. ファイル > 名前を付けて保存 を選択。
  3. JPEG 画像PNG 画像、または WebP 画像 を選ぶ。
  4. 保存する。

ペイントは 1 枚だけの変換なら使える。品質設定もバッチ処理もないので、フォルダー全体の画像には向かない。

PowerShell(ImageMagick)

公式インストーラーから ImageMagick をインストール後:

magick input.bmp output.jpg
magick input.bmp output.png
magick input.bmp output.webp

フォルダー内の一括変換:

Get-ChildItem *.bmp | ForEach-Object {
    magick $_.FullName ($_.BaseName + ".jpg")
}

外部ツールなしの PowerShell

Windows 10 / 11 には .NET イメージングスタックが含まれている。これは BMP から JPG/PNG には使えるが、WebP には追加ライブラリが必要だ。

Add-Type -AssemblyName System.Drawing
$img = [System.Drawing.Image]::FromFile("input.bmp")
$img.Save("output.jpg", [System.Drawing.Imaging.ImageFormat]::Jpeg)
$img.Dispose()

macOS で変換する

プレビュー

  1. BMP をプレビューで開く。
  2. ファイル > 書き出す を選択。
  3. フォーマットドロップダウンから形式を選ぶ。
  4. JPEG の場合は必要に応じて品質を調整する。

プレビューは高速でプライベートだが、ペイントと同様に 1 ファイルずつしか処理できない。

ターミナルで sips を使う

sips は macOS に標準搭載され、BMP、JPEG、PNG、TIFF に対応する。

sips -s format jpeg input.bmp --out output.jpg
sips -s format png input.bmp --out output.png

WebP は ImageMagick か、Homebrew の webp パッケージに含まれる cwebp が必要だ。

brew install webp

# cwebp は BMP を直接読めないので、一度 PNG に変換する
sips -s format png input.bmp --out temp.png
cwebp temp.png -o output.webp
rm temp.png

バッチシェルループ

for f in *.bmp; do
    sips -s format jpeg "$f" --out "${f%.bmp}.jpg"
done

Linux で変換する

ImageMagick

sudo apt install imagemagick

magick input.bmp output.jpg
magick input.bmp output.png
magick input.bmp output.webp

JPEG 品質を調整:

magick input.bmp -quality 90 output.jpg

バッチ変換

for f in *.bmp; do
    magick "$f" "${f%.bmp}.jpg"
done

最小の WebP 出力だけが必要なら cwebp を直接使う。

for f in *.bmp; do
    cwebp -q 85 "$f" -o "${f%.bmp}.webp"
done

コードで変換する

アプリケーションやパイプライン、バックエンドサービス内で変換する必要があるなら、ImageMagick を呼び出すより、ライブラリを直接使う方がすっきりする。

TypeScript / Node.js

sharp を使う。BMP 入力を受け、JPG、PNG、WebP を出力できる。

import sharp from "sharp"

async function convertBmp(
  input: string,
  output: string,
  format: "jpg" | "png" | "webp"
) {
  await sharp(input)
    .toFormat(format, format === "jpg" ? { quality: 90 } : undefined)
    .toFile(output)
}

await convertBmp("input.bmp", "output.jpg", "jpg")
await convertBmp("input.bmp", "output.png", "png")
await convertBmp("input.bmp", "output.webp", "webp")

ブラウザでは sharp は動かない。当社の BMP to WebP コンバーターは WebAssembly を使ってクライアント側でデコードとエンコードを完結させる。

PHP

GD 拡張が有効なら、PHP に組み込みの画像関数がある。

<?php

function bmpToJpg(string $input, string $output, int $quality = 90): void {
    $image = imagecreatefrombmp($input);
    imagejpeg($image, $output, $quality);
    imagedestroy($image);
}

function bmpToPng(string $input, string $output): void {
    $image = imagecreatefrombmp($input);
    imagepng($image, $output);
    imagedestroy($image);
}

function bmpToWebp(string $input, string $output, int $quality = 90): void {
    $image = imagecreatefrombmp($input);
    imagewebp($image, $output, $quality);
    imagedestroy($image);
}

bmpToJpg("input.bmp", "output.jpg");
bmpToPng("input.bmp", "output.png");
bmpToWebp("input.bmp", "output.webp");

Go

Go の標準ライブラリには BMP デコーダーは含まれていないが、golang.org/x/image/bmp で読める。出力は image/jpegimage/pnggolang.org/x/image/webp を使う。

package main

import (
	"image/jpeg"
	"image/png"
	"os"

	"golang.org/x/image/bmp"
	"golang.org/x/image/webp"
)

func bmpToJpg(input, output string, quality int) error {
	f, err := os.Open(input)
	if err != nil {
		return err
	}
	defer f.Close()

	img, err := bmp.Decode(f)
	if err != nil {
		return err
	}

	out, err := os.Create(output)
	if err != nil {
		return err
	}
	defer out.Close()

	return jpeg.Encode(out, img, &jpeg.Options{Quality: quality})
}

PNG と WebP も同じパターンで、png.Encodewebp.Encode を使えばよい。

Java

Java の ImageIO は BMP の読み込みに標準対応している。WebP 出力には webp-imageiocwebp バインディングなどのライブラリが必要だ。

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class BmpConverter {
    public static void bmpToJpg(String input, String output, float quality) throws IOException {
        BufferedImage image = ImageIO.read(new File(input));
        File out = new File(output);
        ImageIO.write(image, "jpg", out);
    }

    public static void bmpToPng(String input, String output) throws IOException {
        BufferedImage image = ImageIO.read(new File(input));
        File out = new File(output);
        ImageIO.write(image, "png", out);
    }
}

JPEG 品質を細かく制御するには JPEGImageWriteParam API を使う。

Python

Pillow を使えば、BMP から各主要形式への変換が最も簡潔に書ける。

from PIL import Image

with Image.open("input.bmp") as img:
    img.convert("RGB").save("output.jpg", quality=90)

with Image.open("input.bmp") as img:
    img.save("output.png")

with Image.open("input.bmp") as img:
    img.save("output.webp", quality=90)

透明度を意識して PNG に出力する場合は RGB 変換を強制しない。

with Image.open("input.bmp") as img:
    img.save("output.png")

よくある落とし穴

  • インデックスカラー BMP。 8 ビット以下の BMP はパレットを使う。明示的に変換しないと、デコーダーがパレットインデックスを返すことがある。Pillow では JPEG や WebP 保存前に img.convert("RGB") を呼ぶ。
  • ボトムアップ方向。 ほとんどのライブラリが自動処理するが、BMP デコーダーを手書きする場合、高さフィールドが正なら行が下から上に格納されていることを覚えておく。
  • JPEG のデフォルト品質。 多くのツールが 75–80 をデフォルトにする。フルスクリーンで見る写真なら 90 が安全。サムネイルなら 70–80 で十分。
  • WebP の互換性。 WebP はブラウザ対応が広いが、一部の古いデスクトップ画像ビューアーでは開けない。対象が Windows ネイティブアプリなら PNG か JPG が安全。

場面別の選択

  • レガシーアーカイブ: 元の BMP を残す。ストレージは安く、正本を失う方が高くつく。
  • Web アップロード: WebP に変換する。フォールバックが必要なら JPG も併せて残す。
  • 印刷や編集ワークフロー: PNG は可逆で圧縮アーティファクトが出ない。
  • メールやメッセージング: JPG が最も安全な汎用形式。

ソフトウェアのインストールもコマンドラインもアップロードも面倒くさいなら、BMP to JPGBMP to PNGBMP to WebP コンバーターを使う。すべてブラウザ内で処理されるため、ファイルは最初から最後までユーザーのマシンに留まる。

その他のおすすめ記事