From 82c74cc2253cfb35a92ea1e1032f7bd6d68b7b7f Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Fri, 12 Jun 2026 21:08:42 -0700 Subject: Move convert into a subdirectory --- convert.go | 149 ----------------------------------------------------- convert/convert.go | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 149 deletions(-) delete mode 100644 convert.go create mode 100644 convert/convert.go diff --git a/convert.go b/convert.go deleted file mode 100644 index d0523ba..0000000 --- a/convert.go +++ /dev/null @@ -1,149 +0,0 @@ -package main - -import ( - "errors" - "flag" - "fmt" - "image" - "image/gif" - "image/jpeg" - "image/png" - "os" - "strings" - - "golang.org/x/image/bmp" - "golang.org/x/image/draw" - "golang.org/x/image/tiff" - _ "golang.org/x/image/webp" -) - -var ( - x = flag.Int("x", 0, "new image width") - y = flag.Int("y", 0, "new image height") - stretch = flag.Bool("stretch", false, "if resizing, whether to stretch the image rather than cropping (the default)") - format = flag.String("format", "", "output image format, default is to use the file extension") -) - -func load(filename string) (image.Image, error) { - file := os.Stdin - if filename != "-" { - var err error - file, err = os.Open(filename) - if err != nil { - return nil, err - } - defer file.Close() - } - - img, _, err := image.Decode(file) - if err != nil { - return nil, fmt.Errorf("decode %q: %s", filename, err) - } - - return img, nil -} - -func divRound(n, d int) int { - return (n + d/2) / d -} - -func resize(img image.Image) image.Image { - x, y := *x, *y - if x == 0 { - x = divRound(y*img.Bounds().Dx(), img.Bounds().Dy()) - } - if y == 0 { - y = divRound(x*img.Bounds().Dy(), img.Bounds().Dx()) - } - output := image.NewRGBA64(image.Rect(0, 0, x, y)) - srcRect := img.Bounds() - if !*stretch { - if img.Bounds().Dx()*y >= img.Bounds().Dy()*x { - scaledX := divRound(img.Bounds().Dy()*x, y) - xOffset := (img.Bounds().Dx() - scaledX) / 2 - srcRect.Min.X += xOffset - srcRect.Max.X = srcRect.Min.X + scaledX - } else { - scaledY := divRound(img.Bounds().Dx()*y, x) - yOffset := (img.Bounds().Dy() - scaledY) / 2 - srcRect.Min.Y += yOffset - srcRect.Max.Y = srcRect.Min.Y + scaledY - } - } - draw.CatmullRom.Scale(output, output.Bounds(), img, srcRect, draw.Src, nil) - return output -} - -func run() error { - args := flag.Args() - if len(args) != 2 { - return errors.New("usage: convert input-file output-file") - } - inputFileName, outputFileName := args[0], args[1] - - ext := *format - if ext == "" { - n := strings.LastIndex(outputFileName, ".") - if n < 0 { - return errors.New("unknown output file extension") - } - ext = outputFileName[n+1:] - } - switch ext { - case "gif", "jpeg", "jpg", "png", "bmp", "tiff": - default: - return fmt.Errorf("unknown output file extension %q", ext) - } - - input, err := load(inputFileName) - if err != nil { - return err - } - - if *x != 0 || *y != 0 { - input = resize(input) - } - - outputFile, err := os.Create(outputFileName) - if err != nil { - return err - } - defer outputFile.Close() - switch ext { - case "gif": - err = gif.Encode(outputFile, input, nil) - case "jpeg", "jpg": - err = jpeg.Encode(outputFile, input, &jpeg.Options{Quality: 100}) - case "png": - err = png.Encode(outputFile, input) - case "bmp": - err = bmp.Encode(outputFile, input) - case "tiff": - err = tiff.Encode(outputFile, input, nil) - } - if err != nil { - return err - } - return outputFile.Close() -} - -func main() { - flag.Usage = func() { - fmt.Fprint(os.Stderr, `Usage: convert input-file output-file -Supported formats: - png - jpeg - bmp - tiff - webp (input only) - -`) - flag.PrintDefaults() - } - flag.Parse() - - if err := run(); err != nil { - fmt.Fprintf(os.Stderr, "convert: %s\n", err) - os.Exit(1) - } -} diff --git a/convert/convert.go b/convert/convert.go new file mode 100644 index 0000000..d0523ba --- /dev/null +++ b/convert/convert.go @@ -0,0 +1,149 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "os" + "strings" + + "golang.org/x/image/bmp" + "golang.org/x/image/draw" + "golang.org/x/image/tiff" + _ "golang.org/x/image/webp" +) + +var ( + x = flag.Int("x", 0, "new image width") + y = flag.Int("y", 0, "new image height") + stretch = flag.Bool("stretch", false, "if resizing, whether to stretch the image rather than cropping (the default)") + format = flag.String("format", "", "output image format, default is to use the file extension") +) + +func load(filename string) (image.Image, error) { + file := os.Stdin + if filename != "-" { + var err error + file, err = os.Open(filename) + if err != nil { + return nil, err + } + defer file.Close() + } + + img, _, err := image.Decode(file) + if err != nil { + return nil, fmt.Errorf("decode %q: %s", filename, err) + } + + return img, nil +} + +func divRound(n, d int) int { + return (n + d/2) / d +} + +func resize(img image.Image) image.Image { + x, y := *x, *y + if x == 0 { + x = divRound(y*img.Bounds().Dx(), img.Bounds().Dy()) + } + if y == 0 { + y = divRound(x*img.Bounds().Dy(), img.Bounds().Dx()) + } + output := image.NewRGBA64(image.Rect(0, 0, x, y)) + srcRect := img.Bounds() + if !*stretch { + if img.Bounds().Dx()*y >= img.Bounds().Dy()*x { + scaledX := divRound(img.Bounds().Dy()*x, y) + xOffset := (img.Bounds().Dx() - scaledX) / 2 + srcRect.Min.X += xOffset + srcRect.Max.X = srcRect.Min.X + scaledX + } else { + scaledY := divRound(img.Bounds().Dx()*y, x) + yOffset := (img.Bounds().Dy() - scaledY) / 2 + srcRect.Min.Y += yOffset + srcRect.Max.Y = srcRect.Min.Y + scaledY + } + } + draw.CatmullRom.Scale(output, output.Bounds(), img, srcRect, draw.Src, nil) + return output +} + +func run() error { + args := flag.Args() + if len(args) != 2 { + return errors.New("usage: convert input-file output-file") + } + inputFileName, outputFileName := args[0], args[1] + + ext := *format + if ext == "" { + n := strings.LastIndex(outputFileName, ".") + if n < 0 { + return errors.New("unknown output file extension") + } + ext = outputFileName[n+1:] + } + switch ext { + case "gif", "jpeg", "jpg", "png", "bmp", "tiff": + default: + return fmt.Errorf("unknown output file extension %q", ext) + } + + input, err := load(inputFileName) + if err != nil { + return err + } + + if *x != 0 || *y != 0 { + input = resize(input) + } + + outputFile, err := os.Create(outputFileName) + if err != nil { + return err + } + defer outputFile.Close() + switch ext { + case "gif": + err = gif.Encode(outputFile, input, nil) + case "jpeg", "jpg": + err = jpeg.Encode(outputFile, input, &jpeg.Options{Quality: 100}) + case "png": + err = png.Encode(outputFile, input) + case "bmp": + err = bmp.Encode(outputFile, input) + case "tiff": + err = tiff.Encode(outputFile, input, nil) + } + if err != nil { + return err + } + return outputFile.Close() +} + +func main() { + flag.Usage = func() { + fmt.Fprint(os.Stderr, `Usage: convert input-file output-file +Supported formats: + png + jpeg + bmp + tiff + webp (input only) + +`) + flag.PrintDefaults() + } + flag.Parse() + + if err := run(); err != nil { + fmt.Fprintf(os.Stderr, "convert: %s\n", err) + os.Exit(1) + } +} -- cgit v1.3.1