12

How to perform RGB->YUV conversion in C/C++?

I have some Bitmap.. RGB I need to convert it to YUV

Libs? Tuts? Articles?

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
Rella
  • 65,003
  • 109
  • 363
  • 636
  • 4
    `s/with actionscript/in C\/C++/` doesn't make it a new question http://stackoverflow.com/questions/1737712/how-to-perform-rgb-yuv-conversion-with-actionscript – Esteban Küber Nov 15 '09 at 15:04
  • 1
    You want to change an RGB value to YUV? Or change a RGB bitmap to a YUV file? You want to make an image file convertion, right? – Esteban Küber Nov 15 '09 at 15:06
  • I'm sure there's a way to be a way to push this work to the gfx card. This kind of operation is perfect for the gfx card. – fishfood Feb 10 '13 at 14:44

2 Answers2

35

You might also want to try these integer only calculations (should be faster than floats)

#define CLIP(X) ( (X) > 255 ? 255 : (X) < 0 ? 0 : X)

// RGB -> YUV
#define RGB2Y(R, G, B) CLIP(( (  66 * (R) + 129 * (G) +  25 * (B) + 128) >> 8) +  16)
#define RGB2U(R, G, B) CLIP(( ( -38 * (R) -  74 * (G) + 112 * (B) + 128) >> 8) + 128)
#define RGB2V(R, G, B) CLIP(( ( 112 * (R) -  94 * (G) -  18 * (B) + 128) >> 8) + 128)

// YUV -> RGB
#define C(Y) ( (Y) - 16  )
#define D(U) ( (U) - 128 )
#define E(V) ( (V) - 128 )

#define YUV2R(Y, U, V) CLIP(( 298 * C(Y)              + 409 * E(V) + 128) >> 8)
#define YUV2G(Y, U, V) CLIP(( 298 * C(Y) - 100 * D(U) - 208 * E(V) + 128) >> 8)
#define YUV2B(Y, U, V) CLIP(( 298 * C(Y) + 516 * D(U)              + 128) >> 8)

// RGB -> YCbCr
#define CRGB2Y(R, G, B) CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16)
#define CRGB2Cb(R, G, B) CLIP((36962 * (B - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)
#define CRGB2Cr(R, G, B) CLIP((46727 * (R - CLIP((19595 * R + 38470 * G + 7471 * B ) >> 16) ) >> 16) + 128)

// YCbCr -> RGB
#define CYCbCr2R(Y, Cb, Cr) CLIP( Y + ( 91881 * Cr >> 16 ) - 179 )
#define CYCbCr2G(Y, Cb, Cr) CLIP( Y - (( 22544 * Cb + 46793 * Cr ) >> 16) + 135)
#define CYCbCr2B(Y, Cb, Cr) CLIP( Y + (116129 * Cb >> 16 ) - 226 )
Leszek Szary
  • 9,763
  • 4
  • 55
  • 62
  • 1
    Isn't it a better answer, comparing to so called "ImageMagick"? – kenmux Jun 13 '16 at 11:21
  • 1
    Your "YUV" is no YUV, because YUV is analog only with different amplitudes for all channels Y, U, V, used in PAL and NTSC TV. YCbCr is the digital representation of YUV in a normalized value range, thus both of your formula sets are YCbCr. The only difference is, that your "YUV" is YCbCr with so-called "studio swing" (reduced value range), whereas your "YCbCr" is YCbCr with so-called "full swing" (full value range). See https://en.wikipedia.org/wiki/YUV – Tobias Knauss Oct 25 '18 at 12:50
19

Check this article: http://www.fourcc.org/fccyvrgb.php Conversion is quite easy so you probably could write your own function based on this

Y  =      (0.257 * R) + (0.504 * G) + (0.098 * B) + 16

Cr = V =  (0.439 * R) - (0.368 * G) - (0.071 * B) + 128

Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128

Previously answered for ActionScript

Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
  • Hi Voyager i need some help i have dumped my code which is yv12->rgb565. In the same way i have to perform for yuv444 to rgb888. Please guide me. Please u can look my latest question for the function which converts yuv12->rgb565 – Abhineet Mar 07 '10 at 06:59
  • 2
    Note that there are several standards governing the colorspace that you might encounter in a yuv file (i.e. BT601, BT709, xvYcc) these formauls will give you a viwable image with most of those, but you may need ot change them to get the coplors "right" (you may also have to clip ot scal the input or output values if you have xvYcc or non-8 bit data – tletnes Jul 15 '11 at 22:45
  • Link mentioned is not working. – Kartik Podugu Mar 23 '23 at 06:41