All formats

golang.org/x/image/bmp

LanguageGo
LicenseBSD 3-Clause
Repositorygithub.com/golang/image (mirror of go.googlesource.com/image)
Documentationpkg.go.dev/golang.org/x/image/bmp
Depends onnothing (pure Go)
Read / writeyes, uncompressed 1, 2, 4, 8, 24 and 32-bit with 40, 108 or 124-byte headers; no RLE, no 16-bit / yes, 8, 24 and 32-bit

golang.org/x/image/bmp is part of the x/image module, the Go project’s supplementary image packages. It has the same API as the standard library codecs: Decode, DecodeConfig and Encode, and importing it registers BMP with image.Decode.

The decoder supports the common BMP files: palette images (1 to 8 bits), 24-bit and 32-bit, top-down or bottom-up, with BITMAPINFOHEADER, V4 or V5 headers. It returns bmp.ErrUnsupported for RLE compression, 16-bit pixels, bit fields with non-standard masks and OS/2 headers. The encoder picks the output from the image type: *image.Gray and *image.Paletted give 8-bit palette files, opaque RGBA images give 24-bit, and images with transparency give 32-bit.

Installation#

Shell
go get golang.org/x/image/bmp

Basic usage: read and write a BMP#

Go
package main

import (
	"fmt"
	"image"
	"image/draw"
	"log"
	"os"

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

func main() {
	f, err := os.Open("in.bmp")
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	img, err := bmp.Decode(f)
	if err != nil {
		log.Fatal(err) // bmp.ErrUnsupported for RLE or 16-bit files
	}
	b := img.Bounds()
	fmt.Printf("%d x %d, %T\n", b.Dx(), b.Dy(), img)

	// mirror horizontally
	out := image.NewRGBA(b)
	draw.Draw(out, b, img, b.Min, draw.Src)
	for y := 0; y < b.Dy(); y++ {
		for x := 0; x < b.Dx()/2; x++ {
			l, r := out.RGBAAt(x, y), out.RGBAAt(b.Dx()-1-x, y)
			out.SetRGBA(x, y, r)
			out.SetRGBA(b.Dx()-1-x, y, l)
		}
	}

	w, err := os.Create("out.bmp")
	if err != nil {
		log.Fatal(err)
	}
	defer w.Close()
	if err := bmp.Encode(w, out); err != nil {
		log.Fatal(err)
	}
}

How to get BMP width and height without decoding#

Go
f, err := os.Open("in.bmp")
if err != nil {
	log.Fatal(err)
}
defer f.Close()
cfg, err := bmp.DecodeConfig(f)
if err != nil {
	log.Fatal(err)
}
fmt.Println(cfg.Width, "x", cfg.Height)

How to convert BMP to PNG#

Go
import (
	"image/png"
	"os"

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

func bmpToPNG(src, dst string) error {
	in, err := os.Open(src)
	if err != nil {
		return err
	}
	defer in.Close()
	img, err := bmp.Decode(in)
	if err != nil {
		return err
	}
	out, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer out.Close()
	return png.Encode(out, img)
}

How to write an 8-bit grayscale BMP#

An *image.Gray is written as an 8-bit BMP with a 256-entry gray palette, a third of the size of a 24-bit file:

Go
gray := image.NewGray(image.Rect(0, 0, 256, 64))
for y := 0; y < 64; y++ {
	for x := 0; x < 256; x++ {
		gray.SetGray(x, y, color.Gray{Y: uint8(x)})
	}
}
err := bmp.Encode(w, gray)

How to open BMP, PNG or JPEG with one function#

Go
import (
	"image"
	_ "image/jpeg"
	_ "image/png"

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

img, format, err := image.Decode(f) // format is "bmp", "png" or "jpeg"

Tips#