NV21转jpeg 实现方法---使用libjpeg库

本文介绍了一种将NV21格式的YUV图像转换为JPEG格式的方法,使用了libjpeg库进行压缩处理。通过读取YUV文件,将其转换为适合JPEG编码的格式,并最终保存为JPEG图像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// N21ToJpg.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

extern "C" {
#include "libjpeg/jpeglib.h"
}

#pragma comment(lib, "libjpeg/jpeg-static.lib")
#define JPEG_QUALITY 90

unsigned int GetTextFileSize(char *filename)
{
	unsigned int  size = 0;
	FILE  *fp = NULL;
	fp = fopen(filename, "rb");
	if (fp)
	{
		fseek(fp, 0, SEEK_END);
		size = ftell(fp);
		fclose(fp);
	}
	return size;
}

bool readFile(char *path, unsigned char *buf, unsigned int &size)
{
	FILE *infile;
	infile = fopen(path, "rb");
	if (!infile)
	{
		return false;
	}
	unsigned int  nActSize = (unsigned int)fread(buf, sizeof(unsigned char), size, infile);
	if (nActSize > size)
	{
		return false;
	}

	size = nActSize;
	fclose(infile);
	return true;
}

//函数参数:pFileName :jpeg 文件名
int Nv21ToJpgFile(const char *pFileName,const char* pYUVBuffer, const int nWidth, const int nHeight)
{
	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;
	JSAMPROW row_pointer[1];
	FILE * pJpegFile = NULL;
	unsigned char *yuvbuf = NULL;
	unsigned char *ybase = NULL, *ubase = NULL;
	int i = 0, j = 0;
	int idx = 0;

	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);

	if ((pJpegFile = fopen(pFileName, "wb")) == NULL)
	{
		return -1;
	}

	jpeg_stdio_dest(&cinfo, pJpegFile);

	// image width and height, in pixels
	cinfo.image_width = nWidth;
	cinfo.image_height = nHeight;
	cinfo.input_components = 3;    // # of color components per pixel
	cinfo.in_color_space = JCS_YCbCr;  //colorspace of input image
	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE);

	cinfo.jpeg_color_space = JCS_YCbCr;
	cinfo.comp_info[0].h_samp_factor = 2;
	cinfo.comp_info[0].v_samp_factor = 2;

	jpeg_start_compress(&cinfo, TRUE);

	if (!(yuvbuf = (unsigned char *)malloc(nWidth * 3)) != NULL)
	{
		return -1;
	}

	memset(yuvbuf, 0, nWidth * 3);

	ybase = (unsigned char *)pYUVBuffer;
	ubase = (unsigned char *)pYUVBuffer + nWidth*nHeight;

	while (cinfo.next_scanline < cinfo.image_height)
	{
		idx = 0;
		for (i = 0; i<nWidth; i++)
		{
			yuvbuf[idx++] = ybase[i + j * nWidth];
			yuvbuf[idx++] = ubase[j / 2 * nWidth + (i / 2) * 2 + 1];//ubase[j / 2 * nWidth + (i / 2) * 2];//nv12
			yuvbuf[idx++] = ubase[j / 2 * nWidth + (i / 2) * 2];//ubase[j / 2 * nWidth + (i / 2) * 2 + 1];
		}
		row_pointer[0] = yuvbuf;
		jpeg_write_scanlines(&cinfo, row_pointer, 1);
		j++;
	}

	jpeg_finish_compress(&cinfo);

	jpeg_destroy_compress(&cinfo);
	fclose(pJpegFile);

	return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
	
	char *path = "D:\\gitcode\\Tftpd64\\Tftpd64\\alg_yuv_480_640_3.yuv";
	char *jpgPath = "D:\\gitcode\\Tftpd64\\Tftpd64\\alg_yuv_480_640_3.jpg";
	unsigned int nSize = GetTextFileSize(path);
	unsigned char *pBuff = new unsigned char[nSize];
	bool bRet = readFile(path, pBuff, nSize);
	Nv21ToJpgFile(jpgPath, (const char*)pBuff,480,640);

	delete[]pBuff;

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值