我有这个问题已经有一段时间了:我正在创建一个模块来处理图像,我的功能之一是遍历图像的每个像素并反转 colored颜色 .该函数在编码时返回预期结果.png图像,但它"饱和".jpeg/jpg图像.

处理时的示例.png图像(正确):https://i.imgur.com/DG35RsR.png

处理时的示例.jpeg图像(错误):https://i.imgur.com/DZQmxJ2.png

我在研究,我发现最接近我的问题,虽然它不是一个答案,是这个问题从围棋库:https://github.com/golang/go/issues/23936

// InvertColors function

func InvertColors(img image.Image) image.Image {
    bounds := img.Bounds()
    width := bounds.Max.X
    height := bounds.Max.Y
    inverted := image.NewRGBA(bounds)

    for y := bounds.Min.Y; y < height; y++ {
        for x := bounds.Min.X; x < width; x++ {
            r, g, b, a := img.At(x, y).RGBA()
            c := color.RGBA{uint8(255 - r), uint8(255 - g), uint8(255 - b), uint8(a)}

            inverted.SetRGBA(x, y, c)
        }
    }

    return inverted
}

// main example
func main() {
    link := "https://i.imgur.com/n5hsdl4.jpg"
    img, err := GetImageFromURL(link)
    if err != nil {
        panic(err)
    }

    buf := new(bytes.Buffer)
    Encode(buf, img, "jpg")
    ioutil.WriteFile("temp.jpg", buf.Bytes(), 0666)

    invImg := InvertColors(img)
    buf = new(bytes.Buffer)
    Encode(buf, invImg, "jpg")
    ioutil.WriteFile("temp2.jpg", buf.Bytes(), 0666)
}

// GetImageFromURL 
func GetImageFromURL(link string) (image.Image, error) {
    _, format, err := ParseURL(link)
    if err != nil {
        return nil, err
    }

    req, err := http.NewRequest("GET", link, nil)
    if err != nil {
        return nil, err
    }

    // Required to make a request.
    req.Close = true
    req.Header.Set("Content-Type", "image/"+format)

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    b, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return nil, err
    }

    img, err := Decode(bytes.NewReader(b), format)
    if err != nil {
        return nil, err
    }

    return img, nil
}

func ParseURL(link string) (u *url.URL, format string, err error) {
    u, err = url.Parse(link)
    if err != nil {
        return u, "", err
    }

    format = u.Path[len(u.Path)-4:]
    if strings.Contains(format, ".") {
        format = strings.Split(format, ".")[1]
    }

    if format != "png" && format != "jpg" && format != "jpeg" {
        return u, "", fmt.Errorf("Unsupported format: %s", format)
    }

    return u, format, nil
}

func Decode(r io.Reader, format string) (img image.Image, err error) {
    if format == "png" {
        img, err = png.Decode(r)
        if err != nil {
            return nil, err
        }

    } else if format == "jpg" || format == "jpeg" {
        img, err = jpeg.Decode(r)
        if err != nil {
            return nil, err
        }

    } else {
        return nil, fmt.Errorf("Unsupported format: %s", format)
    }

    return img, nil
}

推荐答案

您的代码中有两个与 colored颜色 处理相关的错误(第二个可能与此无关).

首先,RGBA()方法返回16位R、G、B、A,但将其视为8位值.

其次,color.RGBA个值是alpha预乘,因此(R, G, B, A)的逆是(A-R, A-G, A-B, A),而不是(MAX-R, MAX-G, MAX-B, A).这可能与此无关,因为您的图片似乎没有任何重要的alpha.

修复代码的一种方法是替换以下内容:

r, g, b, a := img.At(x, y).RGBA()
c := color.RGBA{uint8(255 - r), uint8(255 - g), uint8(255 - b), uint8(a)}

有了这个:

r, g, b, a := img.At(x, y).RGBA()
c := color.RGBA{uint8((a - r)>>8), uint8((a - g)>>8), uint8((a - b)>>8), uint8(a>>8)}

(请注意,您可能会发现,首先将图像转换为image.NRGBA(如果尚未转换),然后在存储图像(非alpha预乘)RGBA通道的底层字节片上迭代要比使用imagecolor包提供的更抽象的接口快得多.)

Go相关问答推荐

正在使用terratest执行terraform脚本测试,但遇到错误退出状态1

+在具有html/模板Golang的Base64中

GORM Find(&;Room)操作使用空数据而不是实际数据填充 struct

JWT 如何解析声明有效性和错误?

如何使用 go 读取 RDF xml 文件中的 XML 命名空间属性

Azure golang SDK - 将 AcrPull 角色分配给 AKS 群集

nixOS 上的 Nginx 反向代理在try 加载 css/js 时返回 404

Golang chromedp Dockerfile

使用GOTK3和librsvg在Go中如何加载内联SVG?

如何忽略打印达到最大深度限制 go colly

如何解决我的 Go 聊天应用程序中 cookie 未在本地主机端口之间传输的问题?

一个Go module可以和之前的非module模块发布在同一个路径下吗?

如何判断范围内的字段?

如何在 Go 中编写示例测试?

Gorm 预加载给出了模糊的列错误

使用自定义处理程序 nats golang 保留订阅方法

将 big.Int 转换为 [2]int64,反之亦然和二进制补码

如何使用带有方法的字符串枚举作为通用参数?

关系不存在 GORM

Golang - 无法从 pipped Windows 命令中获取结果