You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
star/image/image.go

271 lines
6.5 KiB
Go

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("任务完成!")
},
}