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.
271 lines
6.5 KiB
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("任务完成!")
|
|
},
|
|
}
|