Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Golang resize png images using different interpolations
package main
import (
"image"
"image/png"
"log"
"os"
"time"
"golang.org/x/image/draw"
)
const imgFile = "random.png"
func main() {
src := openImage()
// test different scalers;
// scale down to 0.5x0.5 of origin
for _, sc := range []struct {
Name string
Scaler draw.Scaler
}{
{"NearestNeighbor", draw.NearestNeighbor},
{"ApproxBiLinear", draw.ApproxBiLinear},
{"BiLinear", draw.BiLinear},
{"CatmullRom", draw.CatmullRom},
} {
// new size of image
dr := image.Rect(0, 0, src.Bounds().Max.X/2, src.Bounds().Max.Y/2)
// resize using given scaler
var res image.Image
{ // show time to resize
tp := time.Now()
// perform resizing
res = scaleTo(src, dr, sc.Scaler)
// report time to scaling to console
log.Printf("scaling using %q takes %v time",
sc.Name, time.Now().Sub(tp))
}
// open file to save
dstFile, err := os.Create(sc.Name + ".png")
if err != nil {
log.Fatal(err)
}
// encode as .png to the file
err = png.Encode(dstFile, res)
// close the file
dstFile.Close()
if err != nil {
log.Fatal(err)
}
}
}
func openImage() image.Image {
fl, err := os.Open(imgFile)
if err != nil {
log.Fatal(err)
}
defer fl.Close()
img, _, err := image.Decode(fl)
if err != nil {
log.Fatal(err)
}
return img
}
//
// for RGBA images
//
// src - source image
// rect - size we want
// scale - scaler
func scaleTo(src image.Image,
rect image.Rectangle, scale draw.Scaler) image.Image {
dst := image.NewRGBA(rect)
scale.Scale(dst, rect, src, src.Bounds(), draw.Over, nil)
return dst
}
// Timing
// NearestNeighbor 7.935489ms
// ApproxBiLinear 14.876478ms
// BiLinear 113.903067ms
// CatmullRom 115.972061ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.