YUV420图像裁剪demo

该程序读取指定路径的YUV420格式文件,对图像进行裁剪,然后将裁剪后的图像数据保存到新文件中。裁剪功能用于从原始图像中提取特定区域,并调整为新的尺寸。程序涉及内存分配、文件操作和像素处理。
摘要由CSDN通过智能技术生成
/************************************
zhaoym
06/04/2023
************************************/

#include<stdio.h>
#include<dirent.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>

#define OLD_WIDTH 320
#define OLD_HEIGHT 240
#define YUV_SIZE (OLD_WIDTH*OLD_HEIGHT*3/2)
#define NEW_WIDTH 224
#define NEW_HEIGHT 240
#define NEW_YUV_SIZE (NEW_WIDTH*NEW_HEIGHT*3/2)

int crop_yuv420_area(char *input_buffer, int width, int height, char **output_buffer, int new_x, int new_y, int new_width, int new_height)
{
	if(NULL == input_buffer || 0 == width || 0 == height)
		return -1;

	int length = new_width* new_height* 3 / 2;
	*output_buffer = (char *)malloc(length);
	if (*output_buffer == NULL)
	{
		printf("malloc new size memory failed! size=%d\n", length);
		return -1;
	}
	memset(*output_buffer , 0, length);

	char *u_buf = *output_buffer + new_width * new_height;
	char *v_buf = *output_buffer +new_width * new_height * 5 / 4;
	int x = 0,y = 0;
	for(x = 0; x < new_width; x++)
	{
		for (y = 0; y < new_height; y++)
		{
			*(*output_buffer + y * new_width + x) = *(input_buffer + (x + new_x) + width * (y + new_y));
			int ret = (y + new_y)%2;
			if (1 == (x + new_x)%2 && 1 == (y + new_y)%2)
			{
				long pix = width * height + (width>>1) * ((y + new_y)>>1) + (((x + new_x))>>1);
				*(u_buf + (new_width/2)*(y/2) + x/2) = *(input_buffer + pix);

				pix += width * height / 4;
				*(v_buf + (new_width/2)*(y/2) + x/2) = *(input_buffer + pix);
			}
		}
	}

	return 0;
}

int main(int argc, char **argv)
{
	int ret;
	int fd = -1;
	int new_fd = -1;
	char yuv_path[256];
	char yuv_new_path[256];
	char yuv_buf[YUV_SIZE];
	char *yuv_out_buf;

	if(argc < 3) {
		printf("require 2 argument!\n");
		return -1;
	}

	memset(yuv_buf, 0, sizeof(yuv_buf));
	memset(yuv_path, 0, sizeof(yuv_path));
	memset(yuv_new_path, 0, sizeof(yuv_new_path));
	strcpy(yuv_path, argv[1]);
	strcpy(yuv_new_path, argv[2]);

	printf("parsing: %s\n", yuv_path);
	if((fd = open(yuv_path, O_RDWR)) < 0) {
		printf("open %s error\n", yuv_path);
		return -1;
	}
	ret = read(fd, yuv_buf, YUV_SIZE);
	printf("read %d bytes from %s\n", ret, yuv_path);
	
	ret = crop_yuv420_area(yuv_buf, OLD_WIDTH, OLD_HEIGHT, &yuv_out_buf, (OLD_WIDTH - NEW_WIDTH), (OLD_HEIGHT - NEW_HEIGHT), NEW_WIDTH, NEW_HEIGHT);
	if(ret < 0) {
		printf("crop yuv420 error\n");
		return -1;
	}

	if((new_fd = open(yuv_new_path, O_RDWR | O_CREAT)) < 0) {
		printf("open %s error\n", yuv_new_path);
		return -1;
	}

	ret = write(new_fd, yuv_out_buf, NEW_YUV_SIZE);
	printf("save %d bytes to %s\n", ret, yuv_new_path);
	
	free(yuv_out_buf);
	close(fd);
	close(new_fd);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值