douxue7196 2016-06-04 21:59
浏览 71
已采纳

去图像处理

I need to load an image and search for colors and replace them. For example on an image I need to search for all red pixels and convert them to purple.

I am doing the following (img is a valid .png image):

func colorize(img image.Image) {
    b := image.NewRGBA(img.Bounds())
    draw.Draw(b, b.Bounds(), img, image.ZP, draw.Src)
    for x := 0; x < b.Bounds().Dx(); x++ {
        for y := 0; y < b.Bounds().Dy(); y++ {
            log.Println(b.At(x, y).RGBA())
        }
    }
}

Thing is img.At().RGBA() doesn't seem to return the proper R, G, B, A codes? I am getting numbers bigger than 255 for example.

So how should I read all the image pixels while being able to know the x and y position of them?

  • 写回答

1条回答 默认 最新

  • douhui8454 2016-06-04 23:11
    关注

    img.At().RGBA() is Color.RGBA(). Quoting its doc:

    // RGBA returns the alpha-premultiplied red, green, blue and alpha values
    // for the color. Each value ranges within [0, 0xffff], but is represented
    // by a uint32 so that multiplying by a blend factor up to 0xffff will not
    // overflow.
    //
    // An alpha-premultiplied color component c has been scaled by alpha (a),
    // so has valid values 0 <= c <= a.
    

    Components returned by RGBA() are in range 0..0xffff, not 0..0xff, and they are also alpha-premultiplied.

    Manual decoding

    One way to get back the red, green, blue components in the 0..255 range is to shift right by 8 for example:

    r, g, b, a := b.At(x, y).RGBA()
    r, g, b, a = r>>8, g>>8, b>>8, a>>8
    log.Println(r, g, b) // Now in range 0..255
    

    Converting to color.RGBA

    Another way is to convert the color to color.RGBA which is a struct, containing the components plain and simple:

    type RGBA struct {
            R, G, B, A uint8
    }
    

    Since you are using image.NewRGBA() which returns an image of type image.RGBA, the colors returned by the Image.At() method will be of dynamic type color.RGBA, so you can simply use a type assertion:

    rgbacol := b.At(x, y).(color.RGBA)
    log.Println(rgbacol.R, rgbacol.G, rgbacol.B, rgbacol.A)
    

    In general (if image is not of type image.RGBA), Image.At() may or may not be of concrete type color.RGBA.

    So in the general case you need to convert the color to a value of type color.RGBA. Conversions between color models are modeled by color.Model, and the image/color package has predefined converters. What you need is color.RGBAModel. color.RGBAModel.Convert() will return a color.Color value whose dynamic type is surely color.RGBA.

    Example using color.RGBAModel:

    var c color.Color
    c = color.Gray{160}
    
    rgbacol := color.RGBAModel.Convert(c).(color.RGBA)
    
    fmt.Println(rgbacol.R, rgbacol.G, rgbacol.B, rgbacol.A)
    

    Output (try it on the Go Playground):

    160 160 160 255
    

    So in your loop do:

    rgbacol := color.RGBAModel.Convert(b.At(x, y).(color.RGBA)
    // rgbacol is a struct of type color.RGBA, components are in range 0..255
    

    Note:

    Above solutions still give you back the alpha pre-multiplied components. If you want to undo the alpha pre-multiplication, you may use color.NRGBAModel converter (instead of color.RGBAModel).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?