用C语言实现rgb转nv12
时间: 2023-08-05 08:07:46 浏览: 191
以下是一个示例代码实现,实现了RGB图像到NV12图像的转换:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned char r, g, b;
} RGBPixel;
typedef struct {
unsigned char y, u, v;
} YUVPixel;
// 将RGB图像转换为YUV420格式
void rgb_to_yuv(RGBPixel *rgb_image, YUVPixel *yuv_image, int width, int height) {
int i, j;
RGBPixel *rgb_pixel;
YUVPixel *yuv_pixel;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
rgb_pixel = rgb_image + i * width + j;
yuv_pixel = yuv_image + i * width + j;
yuv_pixel->y = (unsigned char)(0.299 * rgb_pixel->r + 0.587 * rgb_pixel->g + 0.114 * rgb_pixel->b);
yuv_pixel->u = (unsigned char)(-0.169 * rgb_pixel->r - 0.331 * rgb_pixel->g + 0.5 * rgb_pixel->b + 128);
yuv_pixel->v = (unsigned char)(0.5 * rgb_pixel->r - 0.419 * rgb_pixel->g - 0.081 * rgb_pixel->b + 128);
}
}
}
// 将YUV420图像转换为NV12格式
void yuv420_to_nv12(YUVPixel *yuv_image, unsigned char *nv12_image, int width, int height) {
int i, j;
YUVPixel *yuv_pixel;
unsigned char *y_plane, *uv_plane;
// Y分量直接拷贝
y_plane = nv12_image;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
y_plane[i * width + j] = (yuv_image[i * width + j].y);
}
}
// UV分量按2x2块进行平均采样
uv_plane = nv12_image + width * height;
for (i = 0; i < height; i += 2) {
for (j = 0; j < width; j += 2) {
yuv_pixel = yuv_image + i * width + j;
*uv_plane++ = (unsigned char)((yuv_pixel[0].u + yuv_pixel[1].u + yuv_pixel[width].u + yuv_pixel[width + 1].u) / 4);
*uv_plane++ = (unsigned char)((yuv_pixel[0].v + yuv_pixel[1].v + yuv_pixel[width].v + yuv_pixel[width + 1].v) / 4);
}
}
}
int main() {
FILE *fp_rgb, *fp_nv12;
int width = 640, height = 480, size = width * height * 3;
RGBPixel *rgb_image;
YUVPixel *yuv_image;
unsigned char *nv12_image;
// 读取RGB图像数据
fp_rgb = fopen("rgb_image.raw", "rb");
rgb_image = (RGBPixel *)malloc(size);
fread(rgb_image, 1, size, fp_rgb);
fclose(fp_rgb);
// 分配YUV420和NV12图像数据空间
yuv_image = (YUVPixel *)malloc(width * height * sizeof(YUVPixel));
nv12_image = (unsigned char *)malloc(width * height * 3 / 2);
// RGB图像转YUV420图像
rgb_to_yuv(rgb_image, yuv_image, width, height);
// YUV420图像转NV12图像
yuv420_to_nv12(yuv_image, nv12_image, width, height);
// 输出NV12图像数据
fp_nv12 = fopen("nv12_image.raw", "wb");
fwrite(nv12_image, 1, width * height * 3 / 2, fp_nv12);
fclose(fp_nv12);
// 释放内存
free(rgb_image);
free(yuv_image);
free(nv12_image);
return 0;
}
```
其中,`RGBPixel`和`YUVPixel`分别表示RGB和YUV像素,`rgb_to_yuv()`函数用于将RGB图像转换为YUV420格式,`yuv420_to_nv12()`函数用于将YUV420图像转换为NV12格式,`main()`函数中读取RGB图像数据并调用两个函数进行转换,最终输出NV12图像数据。
阅读全文