void save_image_data(const char *file_path, const float *image_data, int width, int height) {
// 为了简化,我们分配足够的内存来存储所有的像素数据
// 实际上,你应该检查宽度是否会导致每行的像素数据超过每行的最大字节数
unsigned char *image_data_hwc = malloc(width * height * 3 * sizeof(unsigned char));
int channels = 3;
// 重新排布数据
for (int c = 0; c < channels; ++c) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int src_index = c * height * width + y * width + x;
int dst_index = y * width * channels + x * channels + c;
image_data_hwc[dst_index] = (unsigned char)(image_data[src_index] * 255.0f);
}
}
}
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
// 设置压缩参数
FILE *outfile = fopen(file_path, "wb");
if (outfile == NULL) {
fprintf(stderr, "Error: cannot open output file.\n");
return;
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = channels; // 3 for RGB
cinfo.in_color_space = JCS_RGB; // 颜色空间
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE); // 设置压缩质量
// 开始压缩
jpeg_start_compress(&cinfo, TRUE);
// 为JPEG图像的每一行分配内存
unsigned long row_stride = width * channels;
uint8_t *row_buffer = (uint8_t *)malloc(row_stride);
// 重新排布数据并写入JPEG图像
while (cinfo.next_scanline < cinfo.image_height) {
uint8_t *row_ptr = row_buffer;
for (int x = 0; x < row_stride; x += channels) {
// 从CHW格式中提取RGB值
int chw_index = (cinfo.next_scanline * width + x / channels) * channels + x % channels;
for (int c = 0; c < channels; ++c) {
*row_ptr++ = image_data_hwc[chw_index + c];
}
}
jpeg_write_scanlines(&cinfo, &row_buffer, 1);
}
// 结束压缩
jpeg_finish_compress(&cinfo);
// 清理工作
free(row_buffer);
jpeg_destroy_compress(&cinfo);
fclose(outfile);
free(image_data_hwc);
}
c language save the bin to jpeg.
最新推荐文章于 2024-08-21 14:24:59 发布