I made a program that I use with i3lock.
package main
import (
"flag"
"fmt"
"image"
"image/png"
"log"
"os"
"golang.org/x/image/draw"
)
var (
flagImage = flag.String("i", "", "Path to the image you want to pixelate")
flagOutput = flag.String("o", "", "Path to the output image")
flagScale = flag.Int("p", 0, "How much you want to pixelate. [1-100]")
)
func init() {
flag.Parse()
if *flagImage == "" || *flagOutput == "" {
flag.Usage()
os.Exit(1)
}
if *flagScale < 1 || *flagScale > 100 {
fmt.Println("the -p flag must be between 1-100")
os.Exit(1)
}
}
func main() {
img, err := OpenImage(*flagImage)
if err != nil {
log.Fatalf("could not open image '%s': %s\n", *flagImage, err)
}
scaledDown := Rect(img, 100-*flagScale)
out := ScaleTo(img, scaledDown)
originalSize := Rect(img, 100)
out = ScaleTo(out, originalSize)
err = SaveImage(*flagOutput, out)
if err != nil {
log.Fatalf("could not save file to '%s': %s\n", *flagOutput, err)
}
}
func Rect(img image.Image, scale int) image.Rectangle {
s := float64(scale) / 100
x := int(s * float64(img.Bounds().Max.X))
y := int(s * float64(img.Bounds().Max.Y))
return image.Rect(0, 0, x, y)
}
func ScaleTo(from image.Image, rect image.Rectangle) image.Image {
to := image.NewRGBA(rect)
draw.NearestNeighbor.Scale(to, rect, from, from.Bounds(), draw.Over, nil)
return to
}
func SaveImage(path string, img image.Image) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
err = png.Encode(file, img)
if err != nil {
return err
}
return nil
}
func OpenImage(path string) (image.Image, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
img, err := png.Decode(file)
if err != nil {
return nil, err
}
return img, nil
}
I use it with this script:
#!/usr/bin/bash
VALUE=$1
IMG=/tmp/i3lock.png
maim /tmp/i3lock.png
pixelate -i $IMG -o $IMG -p $VALUE
i3lock -i $IMG
rm $IMG