色彩空间转换
2016-07-27 14:49
429 查看
1. http://blog.csdn.net/yyingwei/article/details/22649575
2
3
//以下是yv12到RGB24的转换算法,如果是yuv420到RGB24转换,秩序u,v反过来就可以了。 //即: // unsigned char* uData = &yData[nYLen]; // unsigned char* vData = &vData[nYLen>>2]; <pre name="code" class="cpp">bool YV12_to_RGB24(unsigned char* pYV12, unsigned char* pRGB24, int iWidth, int iHeight) { if(!pYV12 || !pRGB24) return false; const long nYLen = long(iHeight * iWidth); const int nHfWidth = (iWidth>>1); if(nYLen < 1 || nHfWidth < 1) return false; unsigned char* yData = pYV12; unsigned char* vData = &yData[nYLen]; unsigned char* uData = &vData[nYLen>>2]; if(!uData || !vData) return false; int rgb[3]; int i, j, m, n, x, y; m = -iWidth; n = -nHfWidth; for(y = 0; y < iHeight; y++) { m += iWidth; if(!(y % 2)) n += nHfWidth; for(x=0; x < iWidth; x++) { i = m + x; j = n + (x>>1); rgb[2] = int(yData[i] + 1.370705 * (vData[j] - 128)); // r分量值 rgb[1] = int(yData[i] - 0.698001 * (uData[j] - 128) - 0.703125 * (vData[j] - 128)); // g分量值 rgb[0] = int(yData[i] + 1.732446 * (uData[j] - 128)); // b分量值 j = nYLen - iWidth - m + x; i = (j<<1) + j; for(j=0; j<3; j++) { if(rgb[j]>=0 && rgb[j]<=255) pRGB24[i + j] = rgb[j]; else pRGB24[i + j] = (rgb[j] < 0) ? 0 : 255; } } } return true; }
2
#include "stdio.h" #define ALIGNMENTTO16(size) (((size) + 15) / 16 * 16) void UYVYtoYV12(unsigned char* UYVYBuffer, int ImageWidth, int ImageHeight, unsigned char* YBuffer, unsigned char* UBuffer, unsigned char* VBuffer, int SrcPitch, int DstPitch) { unsigned char* pDestY = YBuffer; unsigned char* pDestU = UBuffer; unsigned char* pDestV = VBuffer; int i; int j; // For each destination U and V pixel for (i = 0; i < ImageHeight / 2; ++i) { for (j = 0; j < ImageWidth / 2; ++j) { int u; int v; // Subsample U u = UYVYBuffer[j * 4]; u += UYVYBuffer[j * 4 + SrcPitch]; u /= 2; pDestU[j] = u; // Subsample V v = UYVYBuffer[j * 4 + 2]; v += UYVYBuffer[j * 4 + 2 + SrcPitch]; v /= 2; pDestV[j] = v; // Copy Y pDestY[j * 2] = UYVYBuffer[j * 4 + 1]; pDestY[j * 2 + 1] = UYVYBuffer[j * 4 + 3]; pDestY[DstPitch + j * 2] = UYVYBuffer[j * 4 + SrcPitch + 1]; pDestY[DstPitch + j * 2 + 1] = UYVYBuffer[j * 4 + SrcPitch + 3]; } pDestY += DstPitch * 2; // Step 2 Y rows pDestU += DstPitch / 2; // Step 1 U row pDestV += DstPitch / 2; // Step 1 V row UYVYBuffer += SrcPitch * 2; // Step 2 source rows } return; } void YUY2toYV12(unsigned char* YUY2Buffer, int ImageWidth, int ImageHeight, unsigned char* YBuffer, unsigned char* UBuffer, unsigned char* VBuffer, int SrcPitch, int DstPitch) { unsigned char* pDestY = YBuffer; unsigned char* pDestU = UBuffer; unsigned char* pDestV = VBuffer; int i; int j; // For each destination U and V pixel for (i = 0; i < ImageHeight / 2; ++i) { for (j = 0; j < ImageWidth / 2; ++j) { int u; int v; // Subsample U u = YUY2Buffer[j * 4 + 1]; u += YUY2Buffer[j * 4 + 1 + SrcPitch]; u /= 2; pDestU[j] = u; // Subsample V v = YUY2Buffer[j * 4 + 3]; v += YUY2Buffer[j * 4 + 3 + SrcPitch]; v /= 2; pDestV[j] = v; // Copy Y pDestY[j * 2] = YUY2Buffer[j * 4]; pDestY[j * 2 + 1] = YUY2Buffer[j * 4 + 2]; pDestY[DstPitch + j * 2] = YUY2Buffer[j * 4 + SrcPitch]; pDestY[DstPitch + j * 2 + 1] = YUY2Buffer[j * 4 + SrcPitch + 2]; } pDestY += DstPitch * 2; // Step 2 Y rows pDestU += DstPitch / 2; // Step 1 U row pDestV += DstPitch / 2; // Step 1 V row YUY2Buffer += SrcPitch * 2; // Step 2 source rows } return; } void YVYUtoYV12( unsigned char *src, int ImageWidth, int ImageHeight, unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch, int DstPitch ) { int i,j; unsigned char *YDst=YBuffer; unsigned char *UDst=UBuffer; unsigned char *VDst=VBuffer; // for each destination u and v pixel for(i=0;i<ImageHeight/2;i++) { for(j=0;j<ImageWidth/2;j++) { int u,v; // subsample u u = src[j*4+3]; u +=src[j*4+3+SrcPitch]; u /= 2; UDst[j] = u ; // subsample v v = src[j*4+1]; v += src[j*4+1+SrcPitch]; v /= 2; VDst[j] = v; // calculate the 4 y's YDst[j*2] = src[j*4]; YDst[j*2+1] = src[j*4+2]; YDst[DstPitch + j*2] = src[j*4+SrcPitch]; YDst[DstPitch + j*2 + 1] = src[j*4+SrcPitch + 2]; } YDst+=DstPitch*2; // step 2 y rows UDst+=DstPitch/2; // step 1 u row VDst+=DstPitch/2; // step 1 v row src+=SrcPitch*2; // step 2 source rows } } void main() { //待转换数据和宽高 LPBYTE SrcBuffer = ?; int width = ?; int height = ?; int YV12BufferSize = ALIGNMENTTO16(width * 3 / 2) * height; LPBYTE YV12Buffer = new BYTE[YV12BufferSize](); LPBYTE pY = YV12Buffer; LPBYTE pV = pY + width * height; LPBYTE pU = pV + width * height / 4; int SrcPitch = ALIGNMENTTO16(width) * 2; int DstPitch = ALIGNMENTTO16(width); // UYYV to YV12 UYVYtoYV12(SrcBuffer, width, height, pY, pU, pV, SrcPitch, DstPitch); // YUV2 to YV12 YUY2toYV12(SrcBuffer, width, height, pY, pU, pV, SrcPitch, DstPitch); // YVYU to YV12 YVYUtoYV12(SrcBuffer, width, height, pY, pU, pV, SrcPitch, DstPitch); delete YV12Buffer; }
3
int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB) { if (NULL == pYUV) { return -1; } unsigned char* pYUVData = (unsigned char *)pYUV; unsigned char* pRGBData = (unsigned char *)pRGB; if (NULL == pRGBData) { if (alphaRGB) { pRGBData = new unsigned char[width*height*4]; } else pRGBData = new unsigned char[width*height*3]; } int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2; int C1, D1, E1, C2; if (alphaRGB) { if (alphaYUV) { for (int i=0; i<height; ++i) { for (int j=0; j<width/2; ++j) { Y1 = *(pYUVData+i*width*3+j*6); U1 = *(pYUVData+i*width*3+j*6+1); Y2 = *(pYUVData+i*width*3+j*6+2); V1 = *(pYUVData+i*width*3+j*6+3); alpha1 = *(pYUVData+i*width*3+j*6+4); alpha2 = *(pYUVData+i*width*3+j*6+5); C1 = Y1-16; C2 = Y2-16; D1 = U1-128; E1 = V1-128; R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8); G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8); B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8); R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8); G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8); B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8); *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1; *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1; *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1; *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha1; *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2; *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2; *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2; *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha2; } } } else { int alpha = 255; for (int i=0; i<height; ++i) { for (int j=0; j<width/2; ++j) { Y1 = *(pYUVData+i*width*2+j*4); U1 = *(pYUVData+i*width*2+j*4+1); Y2 = *(pYUVData+i*width*2+j*4+2); V1 = *(pYUVData+i*width*2+j*4+3); C1 = Y1-16; C2 = Y2-16; D1 = U1-128; E1 = V1-128; R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8); G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8); B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8); R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8); G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8); B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8); *(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1; *(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1; *(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1; *(pRGBData+(height-i-1)*width*4+j*8+3) = alpha; *(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2; *(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2; *(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2; *(pRGBData+(height-i-1)*width*4+j*8+7) = alpha; } } } } else { if (alphaYUV) { for (int i=0; i<height; ++i) { for (int j=0; j<width/2; ++j) { Y1 = *(pYUVData+i*width*3+j*4); U1 = *(pYUVData+i*width*3+j*4+1); Y2 = *(pYUVData+i*width*3+j*4+2); V1 = *(pYUVData+i*width*3+j*4+3); C1 = Y1-16; C2 = Y2-16; D1 = U1-128; E1 = V1-128; R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8); G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8); B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8); R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8); G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8); B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8); *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1; *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1; *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1; *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2; *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2; *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2; } } } else { for (int i=0; i<height; ++i) { for (int j=0; j<width/2; ++j) { Y1 = *(pYUVData+i*width*2+j*4); U1 = *(pYUVData+i*width*2+j*4+1); Y2 = *(pYUVData+i*width*2+j*4+2); V1 = *(pYUVData+i*width*2+j*4+3); C1 = Y1-16; C2 = Y2-16; D1 = U1-128; E1 = V1-128; R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8); G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8); B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8); R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8); G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8); B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8); *(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1; *(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1; *(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1; *(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2; *(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2; *(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2; } } } } return 0; } bool YV12_to_RGB24(unsigned char* pYV12, unsigned char* pRGB24, int iWidth, int iHeight) { if(!pYV12 || !pRGB24) return false; const long nYLen = long(iHeight * iWidth); const int nHfWidth = (iWidth>>1); if(nYLen < 1 || nHfWidth < 1) return false; unsigned char* yData = pYV12; unsigned char* vData = &yData[nYLen]; unsigned char* uData = &vData[nYLen>>2]; if(!uData || !vData) return false; int rgb[3]; int i, j, m, n, x, y; m = -iWidth; n = -nHfWidth; for(y = 0; y < iHeight; y++) { m += iWidth; if(!(y % 2)) n += nHfWidth; for(x=0; x < iWidth; x++) { i = m + x; j = n + (x>>1); rgb[2] = int(yData[i] + 1.370705 * (vData[j] - 128)); // r分量值 rgb[1] = int(yData[i] - 0.698001 * (uData[j] - 128) - 0.703125 * (vData[j] - 128)); // g分量值 rgb[0] = int(yData[i] + 1.732446 * (uData[j] - 128)); // b分量值 j = nYLen - iWidth - m + x; i = (j<<1) + j; for(j=0; j<3; j++) { if(rgb[j]>=0 && rgb[j]<=255) pRGB24[i + j] = rgb[j]; else pRGB24[i + j] = (rgb[j] < 0) ? 0 : 255; } } } return true; }
相关文章推荐
- POJ 1001(大数相乘)
- 搭建struts2环境
- Android中Calendar类的用法总结
- 【iOS】Masonry使用案例讲解
- 浅析Java验证码生成库JCaptcha
- 【POJ】2503 - Babelfish(STL)
- 算法竞赛入门经典(第二版)-刘汝佳-第四章 发放救济金
- 203. Remove Linked List Elements
- android下大文件分割上传
- k-means和bp神经网络要点总结
- 用户级线程和内核级线程
- Matlab 和 C++混合编程
- time wait
- Android 5 消息机制源码分析
- 字符数字之间的转换
- HDU 5755 Gambler Bo(高斯消元解同余方程)
- Lua cocos2d
- gmt_offset变量是干什么的
- 开源软件53个相关概念
- servlet错误:HTTP Status 405 - HTTP method GET is not supported by this URL