package main import ( // "fmt" "os" "image" "log" "image/png" "image/color" "github.com/disintegration/gift" // "math" "flag" ) func LoadImage(filename string) image.Image { reader, err := os.Open(filename) if err != nil { log.Fatal(err) } defer reader.Close() img, _, err := image.Decode(reader) if err != nil { log.Fatal(err) } return img } func SaveImage(filename string, img image.Image) { out, err := os.Create(filename) if err != nil { log.Fatalf("can't write file %s: %v", filename, err) } defer out.Close() err = png.Encode(out, img) if err != nil { log.Fatalf("can't png encode %s: %v", filename, err) } } func UpscaleImage(bounds image.Rectangle, smaller *image.NRGBA, pixel_width int) *image.NRGBA { upscale := image.NewNRGBA(bounds) var from_x, from_y int var from color.Color for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { if x % pixel_width == 0 { from_x = x / pixel_width from_y = y / pixel_width from = smaller.At(from_x, from_y) } upscale.Set(x, y, from) } } return upscale } type Opts struct { InFile string OutFile string PixelWidth int } func ParseOpts() Opts { var opts Opts flag.StringVar(&opts.InFile, "input", "", "input file.png") flag.StringVar(&opts.OutFile, "output", "", "output file.png") flag.IntVar(&opts.PixelWidth, "pixel-width", 4, "pixel width") flag.Parse() return opts } func main() { opts := ParseOpts() src := LoadImage(opts.InFile) bounds := src.Bounds() resize := gift.Resize(bounds.Max.X / opts.PixelWidth, 0, gift.NearestNeighborResampling) g := gift.New(resize) smaller := image.NewNRGBA(g.Bounds(bounds)) g.Draw(smaller, src) upscale := UpscaleImage(bounds, smaller, opts.PixelWidth) SaveImage(opts.OutFile, upscale) }