Here is an example of how to save pic as JPEG or PNG via libjpeg or libpng.
§1 JPEG
int imgwrp_jpeg_quality = 100;
int YUYV_to_JPG(uint8_t* yuvData, int imgWidth, int imgHeight)
{
int retval = 0;
/* ===== open file ===== */
FILE* fp;
fp = fopen("img.jpg", "wb");
if (!fp)
{
retval = 1;
perror("RGB24_to_JPG(): open file");
goto out_return;
}
/* ===== jpg init ===== */
JSAMPROW row_pointer[1];
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr); // init error info first
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, fp);
/* ===== img setting ===== */
cinfo.image_width = imgWidth;
cinfo.image_height = imgHeight;
cinfo.input_components = 3; // color components for each pixel
cinfo.in_color_space = JCS_YCbCr;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, imgwrp_jpeg_quality, FALSE);
jpeg_start_compress(&cinfo, TRUE);
/* ===== write data ===== */
uint8_t* buf = (uint8_t*)malloc(sizeof(uint8_t) * imgWidth * 3);
while (cinfo.next_scanline < cinfo.image_height)
{
for (int i = 0; i < cinfo.image_width; i += 2)
{
buf[i*3] = yuvData[i*2];
buf[i*3+1] = yuvData[i*2+1];
buf[i*3+2] = yuvData[i*2+3];
buf[i*3+3] = yuvData[i*2+2];
buf[i*3+4] = yuvData[i*2+1];
buf[i*3+5] = yuvData[i*2+3];
}
row_pointer[0] = buf;
yuvData += imgWidth * 2;
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
free(buf);
out_close_fp:
if (fp) fclose(fp);
out_return:
return retval;
}
§2 PNG
int RGB24_to_PNG(uint8_t* rgbData, int imgWidth, int imgHeight)
{
int retval = 0;
/* ===== open file ===== */
FILE* fp;
fp = fopen("img.png", "wb");
if (!fp)
{
retval = 1;
perror("RGB24_to_PNG(): open file");
goto out_return;
}
/* ===== png struct ===== */
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!png_ptr || !info_ptr)
{
retval = 2;
perror("RGB24_to_PNG(): png init");
goto out_close_fp;
}
/* ===== io init ===== */
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, imgWidth, imgHeight, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
png_set_packing(png_ptr);
/* ===== write data ===== */
uint8_t* rowData = (uint8_t*)malloc(sizeof(uint8_t) * imgWidth * 3);
int rgbIdx = 0;
// for i rows
for (int i = 0; i < imgHeight; ++i)
{
// copy each row data
for (int j = 0; j < imgWidth; ++j)
{
rowData[j * 3 + 0] = rgbData[rgbIdx++];
rowData[j * 3 + 1] = rgbData[rgbIdx++];
rowData[j * 3 + 2] = rgbData[rgbIdx++];
}
// write row
png_write_row(png_ptr, rowData);
}
png_write_end(png_ptr, info_ptr);
out_free:
if (rowData) free(rowData);
png_destroy_write_struct(&png_ptr, &info_ptr);
out_close_fp:
if (fp) fclose(fp);
out_return:
return retval;
}