Skip to content

Instantly share code, notes, and snippets.

@kbrgl
Created December 23, 2021 10:17
Show Gist options
  • Save kbrgl/c47760b43ef4726222c7c0a4a423b9ec to your computer and use it in GitHub Desktop.
Save kbrgl/c47760b43ef4726222c7c0a4a423b9ec to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"image"
"log"
"os"
"path/filepath"
"strings"
"image/color"
"image/gif"
"image/jpeg"
"image/png"
)
func main() {
if len(os.Args) < 3 {
fmt.Fprintln(os.Stderr, "usage: bwdith <infile> <outfile>")
os.Exit(1)
}
in, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
defer in.Close()
src, _, err := image.Decode(in)
if err != nil {
log.Fatal(err)
}
bounds := src.Bounds()
dst := image.NewGray(bounds)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
var qerr uint8
for x := bounds.Min.X; x < bounds.Max.X; x++ {
gs := color.GrayModel.Convert(src.At(x, y)).(color.Gray)
// distance from white, no need for dfb because that's just gs.Y
oldY := dst.At(x, y).(color.Gray).Y
var dfw uint8
if oldY > 0 {
dfw = 255 - oldY
if dfw < oldY {
qerr = dfw
dst.Set(x, y, color.White)
} else {
qerr = oldY
dst.Set(x, y, color.Black)
}
} else {
dfw = 255 - gs.Y
if dfw < gs.Y {
qerr = dfw
dst.Set(x, y, color.White)
} else {
qerr = gs.Y
dst.Set(x, y, color.Black)
}
}
dst.Set(x+1, y, &color.Gray{qerr * 7 / 16})
dst.Set(x-1, y+1, &color.Gray{qerr * 3 / 16})
dst.Set(x, y+1, &color.Gray{qerr * 5 / 16})
dst.Set(x+1, y+1, &color.Gray{qerr * 1 / 16})
}
}
out, _ := os.OpenFile(fmt.Sprintf("%s", os.Args[2]), os.O_WRONLY|os.O_CREATE, 0600)
defer out.Close()
switch strings.TrimPrefix(filepath.Ext(os.Args[2]), ".") {
case "jpg", "jpeg":
jpeg.Encode(out, dst, nil)
case "png":
png.Encode(out, dst)
case "gif":
gif.Encode(out, dst, nil)
default:
fmt.Fprintln(os.Stderr, "error: output format not supported")
}
}
// getOutName returns a usable name for the outFile.
func getOutName() string {
return "out.png"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment