All formats

image/jpeg

LanguageGo (standard library)
LicenseBSD-3-Clause
Repositorygo.googlesource.com/go
Documentationpkg.go.dev/image/jpeg
Depends onnothing
Read / writeyes / yes; decodes baseline and progressive (8-bit, grayscale, YCbCr, CMYK); encodes baseline 4:2:0

image/jpeg is the JPEG codec of the Go standard library, written in pure Go. jpeg.Decode returns an *image.YCbCr for color images (or *image.Gray, *image.CMYK), jpeg.Encode writes any image.Image. Registering the package with a blank import also lets image.Decode detect JPEG files.

It doesn’t read or write metadata: Exif, ICC and XMP segments are skipped on decode and not written on encode, so phone photos may appear rotated. The encoder writes only baseline JPEG with standard Huffman tables and 4:2:0 subsampling (grayscale images are written as 1-component JPEG). It’s slower than libjpeg-turbo, which has SIMD code.

Installation#

Part of the standard library:

Go
import "image/jpeg"

Basic usage: decode and encode a JPEG#

Go
package main

import (
	"fmt"
	"image/jpeg"
	"log"
	"os"
)

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

	img, err := jpeg.Decode(in)
	if err != nil {
		log.Fatal(err)
	}
	b := img.Bounds()
	fmt.Printf("%d x %d, %T\n", b.Dx(), b.Dy(), img) // *image.YCbCr for color photos

	out, err := os.Create("out.jpg")
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()
	if err := jpeg.Encode(out, img, &jpeg.Options{Quality: 85}); err != nil {
		log.Fatal(err)
	}
}

Quality ranges from 1 to 100; nil options means 75.

How to get JPEG width and height without decoding#

jpeg.DecodeConfig reads markers up to the frame header:

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

How to detect the format and decode any image#

A blank import registers a format with image.Decode:

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

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

How to convert PNG with transparency to JPEG#

Draw onto an opaque background first; the encoder drops alpha and transparent pixels would turn black:

Go
package main

import (
	"image"
	"image/color"
	"image/draw"
	"image/jpeg"
	"image/png"
	"log"
	"os"
)

func main() {
	in, err := os.Open("logo.png")
	if err != nil {
		log.Fatal(err)
	}
	defer in.Close()
	src, err := png.Decode(in)
	if err != nil {
		log.Fatal(err)
	}

	dst := image.NewRGBA(src.Bounds())
	draw.Draw(dst, dst.Bounds(), &image.Uniform{color.White}, image.Point{}, draw.Src)
	draw.Draw(dst, dst.Bounds(), src, src.Bounds().Min, draw.Over)

	out, err := os.Create("logo.jpg")
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()
	if err := jpeg.Encode(out, dst, &jpeg.Options{Quality: 90}); err != nil {
		log.Fatal(err)
	}
}

Tips#