JPG图像以NV21存储
JPG图像以NV21存储
因为遇到一些问题,需要将Jpg图片转化为NV21二进制文件保存,因此,在网上找了很多博客教程,都没能直接解决问题,因此,决定自己动手解决问题。
代码
使用了opencv::cvtColor()
void opencvRGB2NV21(string infile, char* outfile){
Mat Img = cv::imread(infile);
int buflen = (int)(Img.rows * Img.cols * 3 / 2);
unsigned char* pYuvBuf = new unsigned char[buflen];
Mat OpencvYUV;
FILE* fout = fopen(outfile, "wb");
cvtColor(Img, OpencvYUV, CV_BGR2YUV_YV12);
memcpy(pYuvBuf, OpencvYUV.data, buflen*sizeof(unsigned char));
fwrite(pYuvBuf, buflen*sizeof(unsigned char), 1, fout);
fclose(fout);
}
不使用opencv::cvtColor()
void RGB2NV21(string infile, char* outfile){
cv::Mat Img = cv::imread(infile);
FILE *fp = fopen(outfile, "wb");
if (Img.empty()){
std::cout << "empty!check your image";
return;
}
int cols = Img.cols;
int rows = Img.rows;
int Yindex = 0;
int UVindex = rows * cols;
unsigned char* yuvbuff = new unsigned char[int(1.5 * rows * cols)];
cv::Mat OpencvYUV;
cv::Mat OpencvImg;
cv::cvtColor(Img, OpencvYUV, CV_BGR2YUV_YV12);
int UVRow{ 0 };
for (int i=0;i<rows;i++){
for (int j=0;j<cols;j++){
int B = Img.at<cv::Vec3b>(i, j)[0];
int G = Img.at<cv::Vec3b>(i, j)[1];
int R = Img.at<cv::Vec3b>(i, j)[2];
int Y = (77 * R + 150 * G + 29 * B) >> 8;
yuvbuff[Yindex++] = (Y < 0) ? 0 : ((Y > 255) ? 255 : Y);
if (i%2==0&&(j)%2==0)
{
int U = ((-44 * R - 87 * G + 131 * B) >> 8) + 128;
int V = ((131 * R - 110 * G - 21 * B) >> 8) + 128;
yuvbuff[UVindex++] = (V < 0) ? 0 : ((V > 255) ? 255 : V);
yuvbuff[UVindex++] = (U < 0) ? 0 : ((U > 255) ? 255 : U);
}
}
}
for (int i=0;i< 1.5 * rows * cols;i++){
fwrite(&yuvbuff[i], 1, 1, fp);
}
fclose(fp);