用ffmpeg库的方式解码png图片,解码出来的数据是RGB24的格式,通过使用公式将RGB值转换为yuv值
问题描述
根据同事写的解码jpg的代码来写png的,套用下列公式,结果图象是绿屏
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
//同事写的解码jpg图片
int decode_jpg(Stringr filename)
close
.w = 0 //clear screen
BinEditor buf
stdret buf.load(filename)
if buf.size <= 0
return -1
CodecContext* s = avcodec_open_decoder(CODEC_ID_MJPEG)
if s.vptr
s.decode_frame(buf, buf.size)
if s.frame.linesize
alloc(s.w, s.h)
copy_planes(lock(), s)
unlock
avcodec_close2(&s)
return 0
void copy_planes(u8* dst, CodecContext* s)
u8* src = s.frame.data[0]
int linesize = s.frame.linesize
for int y = 0; y < .h; ++y
memcpy(dst, src, .w)
dst += .linesize
src += linesize
linesize >>= PF_PSHIFT(s.pf)//位深度
u8* srcu = s.frame.data[1]
u8* srcv = s.frame.data[2]
for int y = 0; y < .h; y += 2
for int x = 0; x < .w; x += 2
dst[x + 0] = srcv[x >> 1]//右移1 与 +=2对应
dst[x + 1] = srcu[x >> 1]
dst += .linesize
srcu += linesize
srcv += linesize
正常图像:
实际图像:
原因分析:
虽然识别到存储方式为NV12,但是因为NV12是yuv420的一种,所以以为计算的公式是相同的,并且在颜色计算的过程中由于得到的数值是负值(偏移量),没有加128,同时数据强制转换时转换为0,因此显示为绿。
解决方案:
查阅资料,更改为正确的公式,问题解决。
static float Rgb2Y(float r0, float g0, float b0)
{
float y0 = 0.257f*r0 + 0.504f*g0 + 0.098f*b0 + 16.0f;
return y0;
}
//U equals Cb'
//Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
static float Rgb2U(float r0, float g0, float b0)
{
float u0 = -0.148f*r0 - 0.291f*g0 + 0.439f*b0 + 128.0f;
return u0;
}
//V equals Cr'
//Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
static float Rgb2V(float r0, float g0, float b0)
{
float v0 = 0.439f*r0 - 0.368f*g0 - 0.071f*b0 + 128.0f;
return v0;
}