package image import ( "encoding/hex" "fmt" "image" "image/color" "sort" "b612.me/starlog" "github.com/spf13/cobra" ) var useHex bool var useAlpha bool var useCount int var ckt uint8 var fromRgb string var toRgb string func init() { Cmd.AddCommand(imgMirrorCmd, imgRgbCountCmd, imgReplaceCmd, imgReverseCmd) imgRgbCountCmd.Flags().BoolVarP(&useHex, "hex", "x", false, "使用十六进制表示") imgRgbCountCmd.Flags().BoolVarP(&useAlpha, "alpha", "a", false, "统计alpha通道") imgRgbCountCmd.Flags().IntVarP(&useCount, "count", "c", 10, "显示数量") imgReplaceCmd.Flags().Uint8VarP(&ckt, "ckt", "k", 30, "颜色比较阈值") imgReplaceCmd.Flags().StringVarP(&fromRgb, "from", "f", "dfdfdf", "需要替换的颜色") imgReplaceCmd.Flags().StringVarP(&toRgb, "to", "t", "ffffff", "替换为的颜色") } var Cmd = &cobra.Command{ Use: "image", Short: "图像处理", Long: "简单的图像处理工具", Run: func(this *cobra.Command, args []string) { this.Help() }, } var imgMirrorCmd = &cobra.Command{ Use: "mirror", Short: "图像镜像翻转", Long: "图像镜像翻转<水平>", Run: func(this *cobra.Command, args []string) { if len(args) == 0 { starlog.Errorln("请指定需要转换的图像!") return } for _, v := range args { img, err := OpenImage(v) if err != nil { starlog.Errorln(err, v) continue } size := img.Bounds() nimg := image.NewRGBA(size) for x := 0; x < size.Dx(); x++ { for y := 0; y < size.Dy(); y++ { nimg.Set(size.Dx()-x, y, img.At(x, y)) } } if err := SavePhoto(v, nimg); err != nil { starlog.Errorln(err, v) continue } else { fmt.Println(v, "转换已完成!") } } fmt.Println("任务完成!") }, } var imgAlpha = &cobra.Command{ Use: "alpha", Short: "设置透明度", Long: "设置alpha通道透明度", Run: func(this *cobra.Command, args []string) { if len(args) == 0 { starlog.Errorln("请指定需要转换的图像!") return } for _, v := range args { img, err := OpenImage(v) if err != nil { starlog.Errorln(err, v) continue } img = SetAlpha(img, 4) if err := SavePhoto(v, img); err != nil { starlog.Errorln(err, v) continue } else { fmt.Println(v, "转换已完成!") } } fmt.Println("任务完成!") }, } var imgRgbCountCmd = &cobra.Command{ Use: "rgbcount", Short: "统计最多的rgb值", Long: "统计最多的RGB值", Run: func(this *cobra.Command, args []string) { if len(args) == 0 { starlog.Errorln("请指定需要统计的图像!") return } for _, v := range args { img, err := OpenImage(v) if err != nil { starlog.Errorln(err, v) continue } size := img.Bounds() colorMap := make(map[string]int) for x := 0; x < size.Dx(); x++ { for y := 0; y < size.Dy(); y++ { color := img.At(x, y) r, g, b, a := color.RGBA() var key string if useAlpha { if !useHex { key = fmt.Sprintf("%d,%d,%d,%d", uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)) } else { key = fmt.Sprintf("%x%x%x%x", uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)) } } else { if !useHex { key = fmt.Sprintf("%d,%d,%d", uint8(r>>8), uint8(g>>8), uint8(b>>8)) } else { key = fmt.Sprintf("%x%x%x", uint8(r>>8), uint8(g>>8), uint8(b>>8)) } } if _, ok := colorMap[key]; ok { colorMap[key]++ } else { colorMap[key] = 1 } } } colorSlice := make([]struct { string int }, 0, len(colorMap)) for k, v := range colorMap { colorSlice = append(colorSlice, struct { string int }{k, v}) } sort.Slice(colorSlice, func(i, j int) bool { return colorSlice[i].int > colorSlice[j].int }) fmt.Println(v) for i := 0; i < useCount && i < len(colorSlice); i++ { fmt.Printf("%d. %s: %d\n", i+1, colorSlice[i].string, colorSlice[i].int) } fmt.Println("----------------") } fmt.Println("任务完成!") }, } var imgReplaceCmd = &cobra.Command{ Use: "replace", Short: "图像RGB替换", Long: "图像RGB替换", Run: func(this *cobra.Command, args []string) { if len(args) == 0 { starlog.Errorln("请指定需要转换的图像!") return } r, g, b, err := HexToRGB(fromRgb) if err != nil { starlog.Errorln(err) return } nr, ng, nb, err := HexToRGB(toRgb) if err != nil { starlog.Errorln(err) return } for _, v := range args { img, err := OpenImage(v) if err != nil { starlog.Errorln(err, v) continue } size := img.Bounds() nimg := image.NewRGBA(size) for x := 0; x < size.Dx(); x++ { for y := 0; y < size.Dy(); y++ { mR, mG, mB, ma := img.At(x, y).RGBA() mr, mg, mb := uint8(mR>>8), uint8(mG>>8), uint8(mB>>8) nimg.Set(x, y, img.At(x, y)) if mr-r < ckt || r-mr < ckt { if mg-g < ckt || g-mg < ckt { if mb-b < ckt || b-mb < ckt { nimg.Set(x, y, color.NRGBA{nr, ng, nb, uint8(ma >> 8)}) } } } } } if err := SavePhoto("new-"+v, nimg); err != nil { starlog.Errorln(err, v) continue } else { fmt.Println(v, "转换已完成!") } } fmt.Println("任务完成!") }, } func HexToRGB(hexStr string) (uint8, uint8, uint8, error) { // 检查输入长度是否为6 if len(hexStr) != 6 { return 0, 0, 0, fmt.Errorf("invalid hex color string: %s", hexStr) } // 将16进制字符串解码为字节数组 decoded, err := hex.DecodeString(hexStr) if err != nil { return 0, 0, 0, fmt.Errorf("failed to decode hex string: %v", err) } // 解码结果应该有3个字节 if len(decoded) != 3 { return 0, 0, 0, fmt.Errorf("invalid hex color format: %s", hexStr) } // 返回三个通道值 return decoded[0], decoded[1], decoded[2], nil } var imgReverseCmd = &cobra.Command{ Use: "reverse", Short: "图像反色", Long: "图像反色", Run: func(this *cobra.Command, args []string) { if len(args) == 0 { starlog.Errorln("请指定需要转换的图像!") return } for _, v := range args { img, err := OpenImage(v) if err != nil { starlog.Errorln(err, v) continue } size := img.Bounds() nimg := image.NewRGBA(size) for x := 0; x < size.Dx(); x++ { for y := 0; y < size.Dy(); y++ { r, g, b, a := img.At(x, y).RGBA() nimg.Set(x, y, color.NRGBA{uint8(255 - r>>8), uint8(255 - g>>8), uint8(255 - b>>8), uint8(a >> 8)}) } } if err := SavePhoto("reverse-"+v, nimg); err != nil { starlog.Errorln(err, v) continue } else { fmt.Println(v, "转换已完成!") } } fmt.Println("任务完成!") }, }