Search code examples
imagegorgbyuvycbcr

RGB to YUV 420P image conversion in Go


I am wondering, how can I perform conversion from RGB to YUV 420P image in Go (more precisely *image.RGBA to *image.YcbCr). I havn't found any standard method in image package for that. As I also didn't find any library for that, my only idea was to make it pixel by pixel using color.RGBToYCbCr(), but I realised that *image.YcbCr hasn't Set() method for working directly on pixels, so I'm a bit confused. I would be gratuful for some directions or code for that. Greetings


Solution

  • You could use image.NewYCbCr() to create an instance of image.YCbCr whose pixels you can directly manipulate. Then it is just a matter of using color.RGBToYCbCr() for each pixel in the image:

    bounds := original.Bounds()
    converted := image.NewYCbCr(bounds, image.YCbCrSubsampleRatio420)
    
    for row := 0; row < bounds.Max.Y; row++ {
        for col := 0; col < bounds.Max.X; col++ {
            r, g, b, _ := original.At(col, row).RGBA()
            y, cb, cr := color.RGBToYCbCr(uint8(r), uint8(g), uint8(b))
    
            converted.Y[converted.YOffset(col, row)] = y
            converted.Cb[converted.COffset(col, row)] = cb
            converted.Cr[converted.COffset(col, row)] = cr
        }
    }
    

    In the snippet above original is a regular image.RGBA and converted is image.YCbCr. See that the corresponding position pos in the arrays of the color components of converted is computed from the pixel coordinates in original.