Глубокие погружения

Как конвертировать BMP в JPG, PNG и WebP: практическое руководство

koboshiCo-founder
·7 мин чтения
Как конвертировать BMP в JPG, PNG и WebP: практическое руководство
Кратко

BMP легко читать, но дорого хранить. В руководстве — встроенные инструменты ОС, командная строка и конвертация кодом на пяти языках, чтобы вы могли превращать BMP в JPG, PNG или WebP, зная, что делаете.

BMP размером 1920 × 1080 при 24 битах занимает почти 6 МБ. Та же картинка в JPEG качества 90 обычно весит менее 500 КБ. Разница примерно в десять раз — вот почему BMP до сих пор встречается в старых сканерах, медицинском ПО и внутренних компонентах Windows, и почему его почти всегда приходится конвертировать, прежде чем использовать где-либо ещё.

Главное достоинство BMP — простота. Хорошая конвертация — это понимание, когда эта простота помогает, когда мешает, и какой целевой формат на самом деле подходит задаче.

Почему BMP всё ещё существует

BMP хранит пиксели с минимальными накладными расходами на заголовок: никаких таблиц Хаффмана, никакого конечного автомата DEFLATE, никакого хроматического субсэмплирования. Для встроенных систем, устаревших инструментов Windows и любой ситуации, где задача сводится к «прочитал заголовок — скопировал байты», такая простота реально удобна.

Те же ограничения и вытеснили его из повседневного использования:

  • Нет эффективного сжатия. Несжатые BMP огромны. Варианты RLE существуют, но редко превосходят современные кодеки.
  • Нет надёжного альфа-канала. Альфа-байт 32-битного BMP по-разному понимается разными инструментами.
  • Порядок строк снизу вверх. Большинство BMP хранят строки снизу вверх, что добавляет небольшой шаг конвертации для процессов, ожидающих сверху вниз.
  • Нет экосистемы метаданных. Ни EXIF, ни поддержки ICC-профиля в классическом заголовке, ни анимации.

Для архивирования или совместимости BMP подходит. Для веба, почты, мобильных устройств или эффективности хранения он должен стать чем-то другим.

Выбор правильного выходного формата

Прежде чем выполнять команду или писать код, решите, что вы оптимизируете.

ЦельИспользовать когдаКомпромисс
JPGФотографии, превью, любой экранный просмотрС потерями, но очень маленькие файлы
PNGГрафика, скриншоты, всё с прозрачностьюБез потерь, для фото больше JPG
WebPСовременный веб, приложения, где важна пропускная способностьМеньше JPG/PNG, широкая поддержка браузерами

Если вы конвертируете отсканированный документ с текстом и диаграммами, PNG сохранит чёткие края. Если это фото со старого устройства, лучше JPG или WebP. Для веб-раздачи WebP обычно выигрывает по размеру.

Наши браузерные конвертеры BMP to JPG, BMP to PNG и BMP to WebP обрабатывают все три варианта локально: файл остаётся на вашем устройстве.

Конвертация в Windows

Paint

  1. Откройте BMP в Paint.
  2. Выберите Файл > Сохранить как.
  3. Выберите Изображение JPEG, Изображение PNG или Изображение WebP.
  4. Сохраните.

Paint подходит для разовых файлов. Нет контроля качества и пакетной обработки, поэтому для целых папок с изображениями он бесполезен.

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

Preview

  1. Откройте BMP в Preview.
  2. Выберите Файл > Экспортировать.
  3. Выберите формат из выпадающего списка.
  4. При необходимости отрегулируйте качество для JPEG.

Preview работает быстро и локально, но, как и Paint, обрабатывает только по одному файлу.

Терминал с 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 или cwebp из пакета Homebrew webp:

brew install webp

# cwebp не читает BMP напрямую, поэтому сначала конвертируем в PNG
sips -s format png input.bmp --out temp.png
cwebp temp.png -o output.webp
rm temp.png

Пакетный shell-цикл

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

Конвертация в коде

Когда вам нужна конвертация внутри приложения, pipeline или бэкенд-сервиса, обращение к библиотеке обычно удобнее, чем запуск ImageMagick из shell.

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

PHP имеет встроенные функции работы с изображениями, если включено расширение GD.

<?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/jpeg, image/png и golang.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.Encode и webp.Encode.

Java

ImageIO в Java нативно читает BMP. Для вывода WebP нужна библиотека, например webp-imageio или привязки cwebp.

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 используйте API JPEGImageWriteParam.

Python

С Pillow Python — самый простой способ сконвертировать 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. BMP 8 бит и ниже используют палитру. Некоторые декодеры возвращают индексы палитры вместо RGB, если явно не преобразовать. В Pillow перед сохранением в JPEG или WebP используйте img.convert("RGB").
  • Направление снизу вверх. Большинство библиотек обрабатывают это автоматически, но если вы пишете собственный BMP-декодер, помните: положительное значение высоты означает, что строки хранятся снизу вверх.
  • Качество JPEG по умолчанию. Многие инструменты используют 75–80 по умолчанию. Для фото на полный экран 90 безопаснее. Для миниатюр достаточно 70–80.
  • Совместимость WebP. WebP отлично поддерживается браузерами, но может не открываться в некоторых старых десктопных просмотрщиках. Если цель — нативное приложение Windows, безопаснее PNG или JPG.

Что использовать где

  • Устаревшие архивы: храните исходный BMP. Хранилище дешёвое; потерять каноническую версию — нет.
  • Веб-загрузки: конвертируйте в WebP. Если нужен fallback, оставьте копию JPG.
  • Печать или редактирование: PNG остаётся без потерь и избегает артефактов сжатия.
  • Почта и мессенджеры: JPG — самый безопасный универсальный формат.

Если не хочется ничего устанавливать или запускать в терминале, используйте наши конвертеры BMP to JPG, BMP to PNG и BMP to WebP. Всё работает в браузере, и файл остаётся на вашем компьютере от начала до конца.

Ещё посты в блоге