RGB图片处理(3)——RGB转YUV以及彩虹色阶梯图

本文详细介绍了RGB色彩空间到YUV色彩空间的转换算法,并提供了C语言实现。同时,还展示了如何生成RGB彩虹阶梯图,通过编程创建不同颜色层次的图像。内容包括关键公式、代码实现及应用示例。

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

一、RGB与YUV之间的转化关系

Y= 0.299R+0.587G+0.114B
U=-0.147
R-0.289G+0.463B
V= 0.615R-0.515G-0.100*B

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

unsigned char clip_value(unsigned char x, unsigned char min_val, unsigned char  max_val) {
	if (x > max_val) {
		return max_val;
	}
	else if (x < min_val) {
		return min_val;
	}
	else {
		return x;
	}
}

//RGB转YUV
_Bool RGB24_TO_YUV420(unsigned char* RgbBuf, int w, int h, unsigned char* yuvBuf)
{
	unsigned char* ptrY, * ptrU, * ptrV, * ptrRGB;
	memset(yuvBuf, 0, w * h * 3 / 2);
	ptrY = yuvBuf;
	ptrU = yuvBuf + w * h;
	ptrV = ptrU + (w * h * 1 / 4);
	unsigned char y, u, v, r, g, b;
	for (int j = 0; j < h; j++) {
		ptrRGB = RgbBuf + w * j * 3;
		for (int i = 0; i < w; i++) {

			r = *(ptrRGB++);
			g = *(ptrRGB++);
			b = *(ptrRGB++);
			y = (unsigned char)((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
			u = (unsigned char)((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
			v = (unsigned char)((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
			*(ptrY++) = clip_value(y, 0, 255);
			if (j % 2 == 0 && i % 2 == 0) {
				*(ptrU++) = clip_value(u, 0, 255);
			}
			else {
				if (i % 2 == 0) {
					*(ptrV++) = clip_value(v, 0, 255);
				}
			}
		}
	}
	return free;
}


int simplest_rgb24_to_yuv420(char* url_in, int w, int h, int num, char* url_out) {
	FILE* fp = fopen(url_in, "rb+");
	FILE* fp1 = fopen(url_out, "wb+");

	unsigned char* pic_rgb24 = (unsigned char*)malloc(w * h * 3);
	unsigned char* pic_yuv420 = (unsigned char*)malloc(w * h * 3 / 2);

	for (int i = 0; i < num; i++) {
		fread(pic_rgb24, 1, w * h * 3, fp);
		RGB24_TO_YUV420(pic_rgb24, w, h, pic_yuv420);
		fwrite(pic_yuv420, 1, w * h * 3 / 2, fp1);
	}

	free(pic_rgb24);
	free(pic_yuv420);
	fclose(fp);
	fclose(fp1);

	return 0;
}
int main()
{
	simplest_rgb24_to_yuv420("1.rgb",640,640,1,"output.yuv");
}

在这里插入图片描述

二、RGB彩虹阶梯图

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

int rgb24_colcor(int width, int height, char* url_out) 
{
	int barwidth = width / 8;					//每个阶梯的宽度
	char filename[100] = { 0 };		
	FILE* fp = NULL;
	int i = 0, j = 0;
	unsigned char* data = (unsigned char*)malloc(width * height * 3);

	if ((fp = fopen(url_out, "wb+")) == NULL) {
		printf("Error: Cannot create file!");
		return -1;
	}

	for (j = 0; j < height; j++) {
		for (i = 0; i < width; i++) {
			int barnum = i / barwidth;
			//每个阶梯的RGB值
			switch (barnum) {
			case 0: {
				data[(j * width + i) * 3 + 0] = 255;
				data[(j * width + i) * 3 + 1] = 255;
				data[(j * width + i) * 3 + 2] = 255;
				break;
			}
			case 1: {
				data[(j * width + i) * 3 + 0] = 255;
				data[(j * width + i) * 3 + 1] = 255;
				data[(j * width + i) * 3 + 2] = 0;
				break;
			}
			case 2: {
				data[(j * width + i) * 3 + 0] = 0;
				data[(j * width + i) * 3 + 1] = 255;
				data[(j * width + i) * 3 + 2] = 255;
				break;
			}
			case 3: {
				data[(j * width + i) * 3 + 0] = 0;
				data[(j * width + i) * 3 + 1] = 255;
				data[(j * width + i) * 3 + 2] = 0;
				break;
			}
			case 4: {
				data[(j * width + i) * 3 + 0] = 255;
				data[(j * width + i) * 3 + 1] = 0;
				data[(j * width + i) * 3 + 2] = 255;
				break;
			}
			case 5: {
				data[(j * width + i) * 3 + 0] = 255;
				data[(j * width + i) * 3 + 1] = 0;
				data[(j * width + i) * 3 + 2] = 0;
				break;
			}
			case 6: {
				data[(j * width + i) * 3 + 0] = 0;
				data[(j * width + i) * 3 + 1] = 0;
				data[(j * width + i) * 3 + 2] = 255;

				break;
			}
			case 7: {
				data[(j * width + i) * 3 + 0] = 0;
				data[(j * width + i) * 3 + 1] = 0;
				data[(j * width + i) * 3 + 2] = 0;
				break;
			}
			}

		}
	}
	fwrite(data, width * height * 3, 1, fp);
	fclose(fp);
	free(data);

	return 0;
}
int main()
{
	rgb24_colcor(640,480,"color.rgb");
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永不秃头的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值