基於三個分量在記憶體中的排列方式,yuv又分為多種不同的格式。在工作中我遇到過最多的,有如下四種格式:
- nv21
- yuv420sp
- yv12
- yuv420p
名稱排列方式
說明nv21
yyy…vuvu….
y分量在前,vu分量交替排在後面
yuv420sp
yyy…uvuv….
y分量在前,uv分量交替排在後面
yv12
yyy…vv..uu..
y分量在前,其次是v分量,其次是u分量
yuv420p
yyy…uu..vv..
y分量在前,其次是u分量,其次是v分量
是不是繞暈了?其實有規律的,都是y在前面,然後名稱裡帶『s』的,表示uv分量交錯呈現;不帶『s』,表示uv分量分開呈現;最後u、v的順序就要自己查資料了。
// 跳過y分量,將uv『點』相互顛倒一下
int ulen = width*height*0.5;
intlen = width*height;
for (int i=len; i< len + ulen; i++)
// 也是跳過y分量,將uv『塊』顛倒一下
int ulen = width*height*0.5;
int len = width*height;
// 先將u拷貝到臨時buffer
char *ptempu = new
char[ulen];
memcpy(ptempu, pdata +len, ulen);
// 將v拷貝到u
memcpy(pdata + len, pdata + len + ulen, ulen);
// 將u拷貝到v
memcpy(pdata + len + ulen, ptempu, ulen);
yuv的旋轉,實際上是將三個分量都旋轉。我們把三個分量抽象成為二位陣列,那麼y分量的轉換如圖所示:
graph lr
w*h的二維陣列-->h*w的二維陣列
對於帶「s」的uv交錯:
graph lr
w*h/2的二維陣列-->h/2
*w的二維陣列
不帶s的u、v:
graph lr
w/2*h/2的二維陣列-->h/2
*w/2的二維陣列
為了實現轉換,首先我們定義兩個轉換函式(為了提高效率,定義在jni層,c++**實現)
// 旋轉元素為1位元組byte的二維陣列
void rotatebytematrix (jnienv *penv, jclass clazz, jbytearray jbadata, jint offset, jint width, jint height, jint degree)
}memcpy(pdata + offset, ptemp, length);
delete ptemp;}}
else
if (degree == 270)
}memcpy(pdata + offset, ptemp, length);
delete ptemp;}}
penv->releasebytearrayelements(jbadata, pdata, 0);
}
// 旋轉元素為2位元組short的二維陣列
void rotateshortmatrix(jnienv *penv, jclass clazz, jbytearray jsadata, jint offset, jint width, jint height, jint degree)
}memcpy(pdata, ptemp, length
*2);
delete ptemp;}}
else
if (degree == 270)
}memcpy(pdata, ptemp, length
*2);
delete ptemp;}}
penv->releasebytearrayelements(jsadata, (jbyte *)pdata ,0);
}
然後,我們對三個分量分別使用這兩個基礎函式進行旋轉。比如下面兩個例子:
// 1、y,旋轉90度
rotatematrix(src, 0, width, height, 90);
// 2、uv交錯,旋轉90度
offset += width * height;
rotateshortmatrix(src, offset, width / 2, height / 2, degree);
// 1、y,旋轉90度
rotatematrix(src, offset, width, height, degree);
offset += (width * height);
// 2、u,旋轉90度
rotatematrix(src, offset, width / 2, height / 2, degree);
offset += width * height / 4;
// 3、v,旋轉90度
rotatematrix(src, offset, width / 2, height / 2, degree);
yuv格式轉換是那個組織定義的 YUV格式詳解
yuv格式通常有兩大類 打包 packed 格式和平面 planar 格式。前者將yuv分量存放在同乙個陣列中,通常是幾個相鄰的畫素組成乙個巨集畫素 macro pixel 而後者使用三個陣列分開存放yuv三個分量,就像是乙個三維平面一樣。表2.3中的yuy2到y211都是打包格式,而if09到yv...
YUV格式到RGB格式的轉換
yuyv格式到rgb格式的轉換 yuyv格式如下 y0u0y1v0 y2u1y3v1.說明 乙個y代表乙個畫素,而乙個y和uv組合起來構成乙個畫素,所以第0個畫素y0和第乙個畫素y1都是共用第0個畫素的u0和v0。而每個分量y,u,v都是占用乙個位元組的儲存空間。所以y0u0y1v0相當於兩個畫素,...
yuv格式轉換是那個組織定義的 YUV資料格式
概要 yuv格式類別 打包 packed 格式 將每個畫素點的y,u,v分量交叉排列並以畫素點為單元連續的存放在同一陣列中,通常幾個相鄰的畫素組成乙個巨集畫素 macro pixel 平面 planar 格式 使用三個陣列分開連續的存放y,u,v三個分量,即y,u,v分別存放在各自的陣列中。yuv取...