func run(paths []string) { if len(paths) < 2 { log.Fatal("Require 2 or more images") } var data *exif.Exif images := make([]image.Image, len(paths)) for i, path := range paths { // Open file, err := os.Open(path) if err != nil { log.Fatal(path, "\n", err) } defer file.Close() // Decode m, _, err := image.Decode(file) if err != nil { log.Fatal(path, "\n", err) } if i == 0 { file.Seek(0, 0) data = exif.Decode(file) } images[i] = m } // Assume all photos are the same size as the first (stupid!) bounds := images[0].Bounds() // This is the width of a column. It mean that some of the right of an image // may be sacrificed. But it does mean all columns are exact pixels, and are // all exactly the same size. width := bounds.Dx() / len(images) out := image.NewRGBA(image.Rect( bounds.Min.X, bounds.Min.Y, bounds.Min.X+(len(images)*width), bounds.Max.Y, )) for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Min.X+(len(images)*width); x++ { col := x / width out.Set(x, y, images[col].At(x, y)) } } utils.WriteStdout(out, data) }
// ReadStdin reads an image file (either PNG, JPEG or GIF) from standard input. func ReadStdin() (image.Image, *exif.Exif) { img, _, _ := image.Decode(os.Stdin) os.Stdin.Seek(0, 0) data := exif.Decode(os.Stdin) return img, data }