jpg to yuv420sp C语言
时间: 2023-06-10 15:06:16 浏览: 138
将JPEG格式的图片转换为YUV420SP格式,可以使用libjpeg库来读取JPEG图片,然后使用以下代码将RGB格式的图片转换为YUV420SP格式:
```c
#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
// Convert RGB to YUV420SP
void rgb2yuv(unsigned char *rgb, unsigned char *yuv, int width, int height)
{
int frameSize = width * height;
int yIndex = 0;
int uvIndex = frameSize;
int r, g, b, y, u, v;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
r = rgb[j * width * 3 + i * 3];
g = rgb[j * width * 3 + i * 3 + 1];
b = rgb[j * width * 3 + i * 3 + 2];
y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
y = (y < 16) ? 16 : ((y > 255) ? 255 : y);
u = (u < 0) ? 0 : ((u > 255) ? 255 : u);
v = (v < 0) ? 0 : ((v > 255) ? 255 : v);
yuv[yIndex++] = (unsigned char)y;
if (j % 2 == 0 && i % 2 == 0) {
yuv[uvIndex++] = (unsigned char)u;
yuv[uvIndex++] = (unsigned char)v;
}
}
}
}
int main(int argc, char *argv[])
{
if (argc != 3) {
printf("Usage: %s input.jpg output.yuv\n", argv[0]);
return 0;
}
char *input_file = argv[1];
char *output_file = argv[2];
// Read JPEG image
FILE *file = fopen(input_file, "rb");
if (!file) {
printf("Error: Unable to open input file %s\n", input_file);
return 0;
}
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, file);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
int width = cinfo.output_width;
int height = cinfo.output_height;
int numChannels = cinfo.output_components;
int row_stride = width * numChannels;
unsigned char *rgb = (unsigned char *)malloc(width * height * numChannels);
unsigned char *yuv = (unsigned char *)malloc(width * height * 3 / 2);
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
int row = 0;
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer, 1);
for (int i = 0; i < row_stride; i += numChannels) {
rgb[row * row_stride + i] = buffer[0][i];
rgb[row * row_stride + i + 1] = buffer[0][i + 1];
rgb[row * row_stride + i + 2] = buffer[0][i + 2];
}
row++;
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(file);
// Convert RGB to YUV420SP
rgb2yuv(rgb, yuv, width, height);
// Write YUV420SP image
file = fopen(output_file, "wb");
if (!file) {
printf("Error: Unable to open output file %s\n", output_file);
return 0;
}
fwrite(yuv, 1, width * height * 3 / 2, file);
fclose(file);
free(rgb);
free(yuv);
return 0;
}
```
在程序中,首先使用libjpeg库读取JPEG图片,然后将RGB格式的图片转换为YUV420SP格式,最后将YUV420SP格式的图片写入文件。注意,在YUV420SP格式中,Y分量占据前width * height个字节,U和V分量共占据(width * height) / 2个字节。
阅读全文