二、YUV420图像的水平拼接

概述

为了更加理解yuv,下面以YUV420图像作为例子,记录一下进行水平拼接的思路和实现

YUV420

YUV是一种原始图像格式,没有经过编码,比较方便软件处理。本文处理的图像格式为YUV420,图像数据中的亮度Y和色度UV分离,并在内存中连续存储,按照YUYV的方式进行存储。比如一张 4 × 2 图像,以YUV420sp的格式存储就是:Y1Y2Y3Y4Y5Y6Y7Y8U1V1U2V2,所占的内存空间为:width * height * 3 / 2(同理,YUV422所占的内存空间为:width * height * 2)

水平拼接

相较于垂直拼接,水平拼接稍微复杂一些,需要对图像的每一行进行处理。需要将两幅图对应行的Y连接在一起组成新的Y行,对应行的UV连接在一起组成新的UV行,再把新的UV连接到Y后面。用图片描述如下:
水平拼接YUV

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	FILE *file = NULL;
	FILE *yuv1 = NULL;
	FILE *yuv2 = NULL;

	int imgWidth = 1920;
	int imgHeight = 1080;
	int i = 0;

	char filename[64] = {0};
	snprintf(filename, sizeof(filename), "/out.yuv");

	//拼接后的yuv文件
	file = fopen(filename, "w+");
	if (NULL == file)
		return -1;
	
	//拼接前的yuv图像1
	yuv1 = fopen("/yuv001.yuv", "r");
	if (NULL == yuv1)
		return -1;
	
	//拼接前的yuv图像2
	yuv2 = fopen("/yuv002.yuv", "r");
	if (NULL == yuv1)
		return -1;

	char *imgY1, *imgY2;

	//开辟内存
	imgY1 = (char *)malloc(imgWidth * imgHeight * 3 / 2);		//yuv420
	if(NULL == imgY1)
		return -1;
	
	imgY2 = (char *)malloc(imgWidth * imgHeight * 3 /2);		//yuv420
	if(NULL == imgY1)
		return -1;

	//读取拼接前的两张yuv图像数据
	if((imgWidth * imgHeight *3 / 2) != fread(imgY1, 1, imgWidth * imgHeight * 3 / 2, yuv1))
		return -1;
	
	if((imgWidth * imgHeight *3 / 2) != fread(imgY2, 1, imgWidth * imgHeight * 3 / 2, yuv2))
		return -1;

	//水平拼接yuv420
	for (i = 0; i < imgHeight; i++)
	{
		fwrite(imgY1, 1, imgWidth*3/2, file);
		fwrite(imgY2, 1, imgWidth*3/2, file);
		imgY1 += imgWidth*3/2;
		imgY2 += imgWidth*3/2;
	}

	return 0;
}

结果

使用两张1920 * 1080 的YUV图像进行了测试,可以实现水平拼接,也可以多次拼接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值