From ea85769e0388c16125024917ff060090bc6a1fa8 Mon Sep 17 00:00:00 2001 From: areCodeOI <2354452553@qq.com> Date: Sat, 20 Sep 2025 16:37:51 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=86=85=E5=AE=B9=20=E5=AE=8C=E5=96=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/go.yml | 123 ++++++++++++ README.md | 134 +++++++++++++ main.go | 416 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 673 insertions(+) create mode 100644 .github/workflows/go.yml create mode 100644 main.go diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..fe06cf9 --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,123 @@ +name: QRCode-Server + +on: + push: + branches: [ master ] + tags: [ 'v*.*.*' ] # 匹配语义化版本 Tag(如 v1.0.0) + pull_request: + branches: [ master ] + +permissions: + contents: write + +jobs: + code-check: + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 设置 Go 环境 + uses: actions/setup-go@v4 + with: + go-version: '1.24' + cache: true + + - name: 安装依赖 + run: go mod init read-image-color && go mod tidy && go mod verify + + - name: 代码 lint 检查 + uses: golangci/golangci-lint-action@v6 + with: + version: latest + args: --timeout=5m --enable=goimports,revive + + - name: 编译验证 + run: go build -o /dev/null main.go + + + multi-platform-build: + needs: code-check + runs-on: ubuntu-latest + strategy: + fail-fast: false # 某个平台失败不影响其他 + matrix: + # 使用对象数组的方式定义平台配置,确保各维度正确对应 + platform: + - { goos: linux, goarch: amd64, output: "read-image-color-linux-amd64", zip: "linux-amd64.zip" } + - { goos: linux, goarch: arm64, output: "read-image-color-linux-arm64", zip: "linux-arm64.zip" } + - { goos: windows, goarch: amd64, output: "read-image-color-windows-amd64.exe", zip: "windows-amd64.zip" } + - { goos: darwin, goarch: amd64, output: "read-image-color-darwin-amd64", zip: "darwin-amd64.zip" } + - { goos: darwin, goarch: arm64, output: "read-image-color-darwin-arm64", zip: "darwin-arm64.zip" } + steps: + - name: 检出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 设置 Go 环境 + uses: actions/setup-go@v4 + with: + go-version: '1.24' + cache: true + + - name: 安装依赖 + run: go mod init read-image-color && go mod tidy + + - name: 生成版本信息 + id: version + run: | + if [[ "${{ github.ref_type }}" == "tag" ]]; then + VERSION="${{ github.ref_name }}" + else + VERSION="main-$(git rev-parse --short HEAD)" + fi + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: 编译 ${{ matrix.platform.goos }}/${{ matrix.platform.goarch }} 平台 + run: | + # 使用 matrix 中的平台对象变量 + GOOS=${{ matrix.platform.goos }} \ + GOARCH=${{ matrix.platform.goarch }} \ + go build -ldflags "-s -w -X main.version=${{ env.VERSION }}" \ + -o "bin/${{ matrix.platform.output }}" main.go + # 压缩产物 + cd bin && zip ${{ matrix.platform.zip }} ${{ matrix.platform.output }} + + - name: 暂存编译产物 + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.platform.zip }} + path: bin/${{ matrix.platform.zip }} + retention-days: 14 + if-no-files-found: error + + + release: + needs: multi-platform-build + if: github.ref_type == 'tag' + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 下载所有编译产物 + uses: actions/download-artifact@v4 + with: + path: release-artifacts + + - name: 整理产物 + run: | + mkdir -p final-release + find release-artifacts -type f -name "*.zip" -exec mv {} final-release/ \; + + - name: 创建 GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: ${{ github.ref_name }} + body_path: README.md + files: final-release/*.zip + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/README.md b/README.md index a5d3fd3..8bd1aa7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,136 @@ # read-image-color 基于豆包变成实现的go语言的图片大致颜色取色 + + +# 图片颜色数值化统计工具 + +一个基于 Go 语言的图片颜色分析工具,支持提取图片的 RGB/HEX/HSV 量化数据、核心颜色占比统计,无任何语义化颜色名称,仅输出数值化结果,适合数据统计、机器视觉分析等场景。 + + +## 功能特性 +- **数值化输出**:仅保留 RGB、HEX、HSV 量化数据,无颜色名称,聚焦数据本身 +- **核心颜色统计**:按 HSV 色调聚类,自动过滤低占比颜色(≥3%),最多保留 8 种核心颜色 +- **多格式支持**:提供「友好阅读模式」和「JSON 模式」,满足人工查看和程序解析需求 +- **智能缩放**:自动适配图片尺寸(默认 20x20),平衡分析精度与处理速度 +- **代码规范**:通过 `golangci-lint` 全量检查,符合 Go 官方编码规范 + + +## 环境依赖 +- **Go 版本**:1.18+(推荐 1.20+) +- **依赖包**:仅需一个第三方图片缩放库 + ```bash + go get github.com/nfnt/resize@latest + ``` + + +## 快速开始 + +### 1. 安装工具 +```bash +# 克隆代码(或直接下载 main.go) +git clone https://github.com/OIAPI/read-image-color.git +cd read-image-color + +# 安装依赖 +go mod init read-image-color +go get github.com/nfnt/resize@latest +``` + +### 2. 基本使用 +#### (1)友好阅读模式(默认) +适合人工查看,输出格式化的 RGB/HEX/HSV 数据: +```bash +go run main.go -path ./test.jpg +``` +**示例输出**: +``` +====================================== +📷 图片路径:./test.jpg +🖼️ 处理尺寸:20x20 像素(总像素:400) +🎯 整体平均数据: + - 平均RGB:[242, 128, 65] + - 平均HEX:#F28041 + - 平均HSV:[H:22.5°, S:73.2%, V:94.9%] + +🏆 核心颜色统计(共 2 种,占比≥3%): + 1. 占比:68.5% | 像素数:274 | RGB:[245,125,60] | HEX:#F57D3C | HSV:[H:21.8°, S:75.5%, V:96.1%] + 2. 占比:22.3% | 像素数:89 | RGB:[250,180,120] | HEX:#FAB478 | HSV:[H:25.2°, S:52.0%, V:98.0%] +====================================== +``` + +#### (2)JSON 模式(程序解析) +适合后端/前端调用,输出标准 JSON 格式: +```bash +go run main.go -path ./test.jpg -format json -scale 25 +``` +**示例输出**: +```json +{ + "image_path": "./test.jpg", + "process_size": 25, + "total_pixel": 625, + "avg_rgb": [242, 128, 65], + "avg_hex": "#F28041", + "avg_hsv": { + "H": 22.5, + "S": 73.2, + "V": 94.9 + }, + "main_stats": [ + { + "count": 428, + "ratio": 68.5, + "represent_rgb": [245, 125, 60], + "represent_hex": "#F57D3C", + "represent_hsv": { + "H": 21.8, + "S": 75.5, + "V": 96.1 + } + } + ] +} +``` + + +## 命令行参数说明 +| 参数名 | 类型 | 必选 | 默认值 | 说明 | +|--------------|--------|------|---------|----------------------------------------------------------------------| +| `-path` | string | 是 | 无 | 图片路径(支持 PNG/JPG 格式,相对路径或绝对路径均可,如 `./sunset.jpg`) | +| `-format` | string | 否 | `human` | 输出格式:`human`(友好阅读)、`json`(标准 JSON) | +| `-scale` | uint | 否 | 0 | 手动缩放尺寸(如 `25` 表示 25x25 像素,建议 15-50,0 表示智能缩放) | + + +## 代码质量检查 +本项目使用 `golangci-lint` 保障代码规范,执行以下命令可自行检查: +```bash +# 1. 安装 golangci-lint(仅首次需要) +curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2 + +# 2. 执行全量检查 +golangci-lint run ./... +``` + + +## 核心数据说明 +| 字段名 | 含义 | +|------------------|----------------------------------------------------------------------| +| `process_size` | 图片处理时的缩放尺寸(N x N),尺寸越大分析越精细,但速度越慢 | +| `total_pixel` | 处理后的总像素数(= process_size × process_size) | +| `avg_rgb` | 全图像素的 RGB 平均值(每个通道 0-255) | +| `avg_hex` | 平均 RGB 对应的 16 进制颜色码(如 `#FF5733`,可直接用于设计工具) | +| `avg_hsv` | 平均 HSV 值(H: 0-360° 色调,S: 0-100% 饱和度,V: 0-100% 亮度) | +| `main_stats` | 核心颜色列表(占比≥3%),按占比降序排列,包含像素数、代表 RGB/HEX/HSV | + + +## 常见问题 +1. **Q:提示“找不到 goimports/golangci-lint 命令”?** + A:需将 Go 的 `bin` 目录(`$(go env GOPATH)/bin`)添加到系统环境变量,参考 [Go 环境变量配置](https://go.dev/doc/install#install)。 + +2. **Q:支持哪些图片格式?** + A:默认支持 PNG 和 JPG,如需支持其他格式(如 WebP),可在代码中添加对应导入(如 `_ "image/webp"`)。 + +3. **Q:如何调整核心颜色的占比阈值(默认≥3%)?** + A:修改 `GetMainStats` 函数中的 `if ratio < 3.0 { continue }`,将 `3.0` 改为目标阈值(如 `5.0`)。 + +内容由 AI 生成 diff --git a/main.go b/main.go new file mode 100644 index 0000000..3dc99b6 --- /dev/null +++ b/main.go @@ -0,0 +1,416 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "image" + _ "image/jpeg" // 支持 JPG + _ "image/png" // 支持 PNG + "os" + "sort" + + "github.com/nfnt/resize" // 图片缩放库 +) + +// HSV 颜色模型结构体(仅保留数值字段) +type HSV struct { + H float64 // 色调(0-360°) + S float64 // 饱和度(0-100%) + V float64 // 亮度(0-100%) +} + +// Stat 颜色统计结构体(无颜色名称,仅量化信息) +type Stat struct { + Count int `json:"count"` // 像素数量 + Ratio float64 `json:"ratio"` // 占比(%) + RepresentRGB [3]int `json:"represent_rgb"` // 代表RGB值 + RepresentHex string `json:"represent_hex"` // 代表16进制码 + RepresentHSV HSV `json:"represent_hsv"` // 代表HSV值 +} + +// Result 输出结构体(无颜色名称,仅量化结果) +type Result struct { + ImagePath string `json:"image_path"` // 图片路径 + ProcessSize int `json:"process_size"` // 处理尺寸(N x N) + TotalPixel int `json:"total_pixel"` // 总像素数 + AvgRGB [3]int `json:"avg_rgb"` // 整体平均RGB + AvgHex string `json:"avg_hex"` // 整体平均16进制 + AvgHSV HSV `json:"avg_hsv"` // 整体平均HSV + MainStats []Stat `json:"main_stats"` // 核心颜色统计(最多8种,占比≥3%) +} + +// RGBToHex:RGB转16进制(如 [255,127,0] → #FF7F00) +func RGBToHex(rgb [3]int) string { + // 确保RGB值在0-255范围内 + for i := 0; i < 3; i++ { + if rgb[i] < 0 { + rgb[i] = 0 + } else if rgb[i] > 255 { + rgb[i] = 255 + } + } + return fmt.Sprintf("#%02X%02X%02X", rgb[0], rgb[1], rgb[2]) +} + +// RGBToHSV:RGB转HSV(数值标准化) +func RGBToHSV(r, g, b int) HSV { + rf := float64(r) / 255.0 + gf := float64(g) / 255.0 + bf := float64(b) / 255.0 + + maxVal := max3f(rf, gf, bf) + minVal := min3f(rf, gf, bf) + delta := maxVal - minVal + + var h, s, v float64 + + // 亮度V(0-100%) + v = maxVal * 100.0 + + // 无色彩差异(灰/黑/白) + if maxVal == 0 || delta == 0 { + s = 0.0 + h = 0.0 + return HSV{H: h, S: s, V: v} + } + + // 饱和度S(0-100%) + s = (delta / maxVal) * 100.0 + + // 色调H(0-360°) + switch maxVal { + case rf: + h = 60.0 * (((gf - bf) / delta) + 6) + case gf: + h = 60.0 * (((bf - rf) / delta) + 2) + case bf: + h = 60.0 * (((rf - gf) / delta) + 4) + } + + // 确保H在0-360范围内 + if h < 0 { + h += 360.0 + } + + return HSV{H: h, S: s, V: v} +} + +// GetImageData:读取图片并提取RGB+HSV数据 +func GetImageData(imgPath string) ([][3]int, []HSV, uint, error) { + // 校验文件存在 + if _, err := os.Stat(imgPath); err != nil { + return nil, nil, 0, fmt.Errorf("图片不存在:%s", imgPath) + } + + // 打开并解码图片 + file, err := os.Open(imgPath) + if err != nil { + return nil, nil, 0, fmt.Errorf("打开失败:%w", err) + } + defer func() { + if closeErr := file.Close(); closeErr != nil { + fmt.Printf("⚠️ 关闭图片文件时警告:%v\n", closeErr) + } + }() + + img, imgFormat, err := image.Decode(file) + if err != nil { + return nil, nil, 0, fmt.Errorf("不支持的格式(仅PNG/JPG),检测到:%s", imgFormat) + } + + // 智能缩放(20x20,平衡精度与速度) + imgBounds := img.Bounds() + imgW, imgH := imgBounds.Max.X, imgBounds.Max.Y + scaleSize := uint(20) + if imgW <= 250 && imgH <= 250 { + scaleSize = uint(imgW) + if uint(imgH) < scaleSize { + scaleSize = uint(imgH) + } + } + resizedImg := resize.Resize(scaleSize, scaleSize, img, resize.Lanczos3) + + // 提取RGB和HSV数组 + var rgbArr [][3]int + var hsvArr []HSV + bounds := resizedImg.Bounds() + for y := 0; y < bounds.Max.Y; y++ { + for x := 0; x < bounds.Max.X; x++ { + r, g, b, _ := resizedImg.At(x, y).RGBA() + r8, g8, b8 := int(r>>8), int(g>>8), int(b>>8) + rgbArr = append(rgbArr, [3]int{r8, g8, b8}) + hsvArr = append(hsvArr, RGBToHSV(r8, g8, b8)) + } + } + + return rgbArr, hsvArr, scaleSize, nil +} + +// GetMainStats:提取核心颜色统计(按HSV聚类,无名称分类) +func GetMainStats(rgbArr [][3]int, hsvArr []HSV) ([]Stat, [3]int, string, HSV) { + total := len(rgbArr) + if total == 0 || len(hsvArr) != total { + defaultRGB := [3]int{0, 0, 0} + return nil, defaultRGB, RGBToHex(defaultRGB), HSV{} + } + + // 按HSV近似聚类(简化:按Hue区间聚类,每15°一个区间,共24类) + type tempStat struct { + count int + sumR int + sumG int + sumB int + sumH float64 + sumS float64 + sumV float64 + } + // 用Hue区间作为key(0-15°,15-30°,...345-360°),共24个区间 + statMap := make(map[int]tempStat) + overallSumR, overallSumG, overallSumB := 0, 0, 0 + overallSumH, overallSumS, overallSumV := 0.0, 0.0, 0.0 + + // 遍历像素统计 + for i := 0; i < total; i++ { + rgb := rgbArr[i] + hsv := hsvArr[i] + + // 累计整体平均值 + overallSumR += rgb[0] + overallSumG += rgb[1] + overallSumB += rgb[2] + overallSumH += hsv.H + overallSumS += hsv.S + overallSumV += hsv.V + + // 计算当前像素的Hue区间(15°为步长,0→0-15°,1→15-30°,...23→345-360°) + hueKey := int(hsv.H / 15) + if hueKey >= 24 { // 处理345-360°(hueKey=24时归为23) + hueKey = 23 + } + + // 更新对应区间的统计 + temp := statMap[hueKey] + temp.count++ + temp.sumR += rgb[0] + temp.sumG += rgb[1] + temp.sumB += rgb[2] + temp.sumH += hsv.H + temp.sumS += hsv.S + temp.sumV += hsv.V + statMap[hueKey] = temp + } + + // 计算整体平均RGB、HEX、HSV + avgRGB := [3]int{ + overallSumR / total, + overallSumG / total, + overallSumB / total, + } + avgHex := RGBToHex(avgRGB) + avgHSV := HSV{ + H: round1(overallSumH / float64(total)), + S: round1(overallSumS / float64(total)), + V: round1(overallSumV / float64(total)), + } + + // 转换为Stat结构体,过滤低占比(≥3%) + var mainStats []Stat + for _, temp := range statMap { + ratio := float64(temp.count) / float64(total) * 100.0 + if ratio < 3.0 { + continue + } + + // 计算该区间的代表值(平均值) + repRGB := [3]int{ + temp.sumR / temp.count, + temp.sumG / temp.count, + temp.sumB / temp.count, + } + repHex := RGBToHex(repRGB) + repHSV := HSV{ + H: round1(temp.sumH / float64(temp.count)), + S: round1(temp.sumS / float64(temp.count)), + V: round1(temp.sumV / float64(temp.count)), + } + + mainStats = append(mainStats, Stat{ + Count: temp.count, + Ratio: round1(ratio), + RepresentRGB: repRGB, + RepresentHex: repHex, + RepresentHSV: repHSV, + }) + } + + // 按占比降序排序,最多保留8种 + sort.Slice(mainStats, func(i, j int) bool { + return mainStats[i].Ratio > mainStats[j].Ratio + }) + if len(mainStats) > 8 { + mainStats = mainStats[:8] + } + + return mainStats, avgRGB, avgHex, avgHSV +} + +// round1:保留1位小数(四舍五入) +func round1(num float64) float64 { + return float64(int(num*10 + 0.5)) / 10 +} + +// max3f:计算3个float64的最大值 +func max3f(a, b, c float64) float64 { + maxVal := a + if b > maxVal { + maxVal = b + } + if c > maxVal { + maxVal = c + } + return maxVal +} + +// min3f:计算3个float64的最小值 +func min3f(a, b, c float64) float64 { + minVal := a + if b < minVal { + minVal = b + } + if c < minVal { + minVal = c + } + return minVal +} + +func main() { + // 命令行参数定义 + var ( + imgPath string // 图片路径(必填) + scaleSize uint // 手动缩放尺寸(可选) + outputFormat string // 输出格式(human/json) + ) + flag.StringVar(&imgPath, "path", "", "图片路径(必填,示例:./test.jpg)") + flag.UintVar(&scaleSize, "scale", 0, "手动缩放尺寸(可选,如20=20x20,建议15-30)") + flag.StringVar(&outputFormat, "format", "human", "输出格式:human(友好阅读)/json(标准JSON)") + + // 自定义帮助信息 + flag.Usage = func() { + fmt.Println("图片颜色数值化统计工具(仅输出RGB/HEX/HSV量化结果)") + fmt.Println("用法:go run main.go -path 图片路径 [选项]") + fmt.Println("选项:") + flag.PrintDefaults() + fmt.Println("\n示例:") + fmt.Println(" 1. 友好模式:go run main.go -path ./sunset.jpg") + fmt.Println(" 2. JSON模式:go run main.go -path ./sky.jpg -format json -scale 20") + } + flag.Parse() + + // 参数校验 + if imgPath == "" { + fmt.Println("❌ 错误:请通过 -path 参数指定图片路径(如 -path ./test.png)") + flag.Usage() + os.Exit(1) + } + if outputFormat != "human" && outputFormat != "json" { + fmt.Printf("❌ 错误:-format 仅支持 human 或 json,当前输入:%s\n", outputFormat) + os.Exit(1) + } + if scaleSize > 50 { + fmt.Println("❌ 错误:-scale 最大值为50(过大影响处理速度)") + os.Exit(1) + } + + // 读取图片数据 + rgbArr, hsvArr, autoScale, err := GetImageData(imgPath) + if err != nil { + fmt.Printf("❌ 图片处理失败:%v\n", err) + os.Exit(1) + } + + // 手动缩放尺寸覆盖(若指定) + if scaleSize > 0 && scaleSize != autoScale { + file, err := os.Open(imgPath) + if err != nil { + fmt.Printf("❌ 重新打开图片失败:%v\n", err) + os.Exit(1) + } + defer func() { + if closeErr := file.Close(); closeErr != nil { + fmt.Printf("⚠️ 关闭图片文件时警告:%v\n", closeErr) + } + }() + + img, _, err := image.Decode(file) + if err != nil { + fmt.Printf("❌ 重新解码图片失败:%v\n", err) + os.Exit(1) + } + resizedImg := resize.Resize(scaleSize, scaleSize, img, resize.Lanczos3) + + // 重新提取数据 + rgbArr, hsvArr = nil, nil + bounds := resizedImg.Bounds() + for y := 0; y < bounds.Max.Y; y++ { + for x := 0; x < bounds.Max.X; x++ { + r, g, b, _ := resizedImg.At(x, y).RGBA() + r8, g8, b8 := int(r>>8), int(g>>8), int(b>>8) + rgbArr = append(rgbArr, [3]int{r8, g8, b8}) + hsvArr = append(hsvArr, RGBToHSV(r8, g8, b8)) + } + } + autoScale = scaleSize + } + + // 提取核心统计结果 + mainStats, avgRGB, avgHex, avgHSV := GetMainStats(rgbArr, hsvArr) + + // 构建输出结果 + result := Result{ + ImagePath: imgPath, + ProcessSize: int(autoScale), + TotalPixel: len(rgbArr), + AvgRGB: avgRGB, + AvgHex: avgHex, + AvgHSV: avgHSV, + MainStats: mainStats, + } + + // 输出 + if outputFormat == "json" { + jsonData, err := json.MarshalIndent(result, "", " ") + if err != nil { + fmt.Printf("❌ JSON序列化失败:%v\n", err) + os.Exit(1) + } + fmt.Println(string(jsonData)) + } else { + // 友好阅读模式:仅展示量化数据(RGB/HEX/HSV/占比),无任何颜色名称 + fmt.Println("======================================") + fmt.Printf("📷 图片路径:%s\n", result.ImagePath) + fmt.Printf("🖼️ 处理尺寸:%dx%d 像素(总像素:%d)\n", + result.ProcessSize, result.ProcessSize, result.TotalPixel) + fmt.Println("🎯 整体平均数据:") + fmt.Printf(" - 平均RGB:[%d, %d, %d]\n", + result.AvgRGB[0], result.AvgRGB[1], result.AvgRGB[2]) + fmt.Printf(" - 平均HEX:%s\n", result.AvgHex) + fmt.Printf(" - 平均HSV:[H:%.1f°, S:%.1f%%, V:%.1f%%]\n", + result.AvgHSV.H, result.AvgHSV.S, result.AvgHSV.V) + + // 输出核心统计列表(按占比排序,无颜色名称) + if len(result.MainStats) > 0 { + fmt.Printf("\n🏆 核心颜色统计(共 %d 种,占比≥3%%):\n", len(result.MainStats)) + for i, stat := range result.MainStats { + fmt.Printf(" %d. 占比:%.1f%% | 像素数:%d | RGB:[%d,%d,%d] | HEX:%s | HSV:[H:%.1f°, S:%.1f%%, V:%.1f%%]\n", + i+1, stat.Ratio, stat.Count, + stat.RepresentRGB[0], stat.RepresentRGB[1], stat.RepresentRGB[2], + stat.RepresentHex, + stat.RepresentHSV.H, stat.RepresentHSV.S, stat.RepresentHSV.V) + } + } else { + fmt.Println("\n⚠️ 未检测到占比≥3%的核心颜色(所有颜色占比均较低)") + } + fmt.Println("======================================") + } +} From 6c06b8cc3b6e022aab3ec2791146c83412f5ee24 Mon Sep 17 00:00:00 2001 From: areCodeOI <2354452553@qq.com> Date: Sat, 20 Sep 2025 16:45:13 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=86=85=E5=AE=B9=20=E5=AE=8C=E5=96=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index fe06cf9..b788996 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,7 +2,7 @@ name: QRCode-Server on: push: - branches: [ master ] + branches: [ main ] tags: [ 'v*.*.*' ] # 匹配语义化版本 Tag(如 v1.0.0) pull_request: branches: [ master ] From 6d6278190cc4fcedf37934ee77dc21544973e405 Mon Sep 17 00:00:00 2001 From: areCodeOI <2354452553@qq.com> Date: Sat, 20 Sep 2025 16:50:25 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b788996..59c9d62 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,7 @@ on: branches: [ main ] tags: [ 'v*.*.*' ] # 匹配语义化版本 Tag(如 v1.0.0) pull_request: - branches: [ master ] + branches: [ main ] permissions: contents: write