github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/imgutils/imgutils.go (about) 1 package imgutils 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/nfnt/resize" 7 "github.com/pkg/errors" 8 "github.com/unionj-cloud/go-doudou/v2/toolkit/caller" 9 "github.com/unionj-cloud/go-doudou/v2/toolkit/stringutils" 10 "image" 11 "image/draw" 12 "image/gif" 13 "image/jpeg" 14 "image/png" 15 "io" 16 "os" 17 "path/filepath" 18 ) 19 20 func ResizeKeepAspectRatio(input io.Reader, multiplier float64, output string) (string, error) { 21 by, err := io.ReadAll(input) 22 if err != nil { 23 return "", errors.Wrap(err, caller.NewCaller().String()) 24 } 25 imgConf, imgType, err := image.DecodeConfig(bytes.NewReader(by)) 26 if err != nil { 27 return "", errors.Wrap(err, caller.NewCaller().String()) 28 } 29 switch imgType { 30 case "jpeg": 31 img, err := jpeg.Decode(bytes.NewReader(by)) 32 if err != nil { 33 return "", errors.Wrap(err, caller.NewCaller().String()) 34 } 35 m := resize.Resize(uint(float64(imgConf.Width)*multiplier), 0, img, resize.Lanczos3) 36 if stringutils.IsEmpty(filepath.Ext(output)) { 37 output += fmt.Sprintf(".%s", imgType) 38 } 39 out, err := os.Create(output) 40 if err != nil { 41 return "", errors.Wrap(err, caller.NewCaller().String()) 42 } 43 defer out.Close() 44 jpeg.Encode(out, m, nil) 45 case "png": 46 img, err := png.Decode(bytes.NewReader(by)) 47 if err != nil { 48 return "", errors.Wrap(err, caller.NewCaller().String()) 49 } 50 m := resize.Resize(uint(float64(imgConf.Width)*multiplier), 0, img, resize.Lanczos3) 51 if stringutils.IsEmpty(filepath.Ext(output)) { 52 output += fmt.Sprintf(".%s", imgType) 53 } 54 out, err := os.Create(output) 55 if err != nil { 56 return "", errors.Wrap(err, caller.NewCaller().String()) 57 } 58 defer out.Close() 59 png.Encode(out, m) 60 case "gif": 61 img, err := gif.DecodeAll(bytes.NewReader(by)) 62 if err != nil { 63 return "", errors.Wrap(err, caller.NewCaller().String()) 64 } 65 if multiplier != 1 { 66 for i, item := range img.Image { 67 resized := resize.Resize(uint(float64(imgConf.Width)*multiplier), 0, item, resize.Lanczos3) 68 rgba64 := resized.(*image.RGBA64) 69 palettedImage := image.NewPaletted(rgba64.Bounds(), getSubPalette(rgba64)) 70 draw.Draw(palettedImage, palettedImage.Rect, rgba64, rgba64.Bounds().Min, draw.Src) 71 img.Image[i] = palettedImage 72 } 73 } 74 if stringutils.IsEmpty(filepath.Ext(output)) { 75 output += fmt.Sprintf(".%s", imgType) 76 } 77 out, err := os.Create(output) 78 if err != nil { 79 return "", errors.Wrap(err, caller.NewCaller().String()) 80 } 81 defer out.Close() 82 gif.EncodeAll(out, img) 83 } 84 return output, nil 85 }