Skip to content

Instantly share code, notes, and snippets.

@agosto-calvinbehling
Last active November 19, 2015 14:21
Show Gist options
  • Save agosto-calvinbehling/012c237d424b6f0e632c to your computer and use it in GitHub Desktop.
Save agosto-calvinbehling/012c237d424b6f0e632c to your computer and use it in GitHub Desktop.
PNG compression
package main
import (
"fmt"
"image/png"
"os"
)
// DefaultCompression
// NoCompression
// BestSpeed
// BestCompression
const COMPRESSION_LEVEL = png.BestSpeed
const FILE_PERM = 0666
func main() {
var inputPath, outputPath string
argc := len(os.Args)
if argc <= 1 || argc > 3 {
fmt.Println("Usage: gopng <input.png> [output.png]")
os.Exit(1)
} else if argc == 3 {
outputPath = os.Args[2]
}
inputPath = os.Args[1]
err := Crush(inputPath, outputPath, COMPRESSION_LEVEL)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func Crush(inputPath, outputPath string, compressionLevel png.CompressionLevel) error {
var outputFile *os.File
openFlags := os.O_RDONLY
overwrite := outputPath == ""
if overwrite {
openFlags = os.O_RDWR
}
inputFile, err := os.OpenFile(inputPath, openFlags, FILE_PERM)
if err != nil {
return fmt.Errorf("Unable to open input file: %s", err)
}
defer inputFile.Close()
image, err := png.Decode(inputFile)
if err != nil {
return fmt.Errorf("Unable to decode input file: %s", err)
}
if overwrite {
outputFile = inputFile
if ioOffset, err := outputFile.Seek(0, 0); ioOffset != 0 || err != nil {
return fmt.Errorf("Unable to seek to start of output file (offset: %d): %s", ioOffset, err)
}
if err := outputFile.Truncate(0); err != nil {
return fmt.Errorf("Unable to truncate output file: %s", err)
}
} else {
outputFile, err = os.Create(outputPath)
if err != nil {
return fmt.Errorf("Unable to create output file: %s", err)
}
defer outputFile.Close()
}
encoder := png.Encoder{CompressionLevel: compressionLevel}
err = encoder.Encode(outputFile, image)
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment