使用 libjpeg 将 RGB 值保存为 jpeg,得到奇怪的结果
Save RGB values to jpeg use libjpeg, getting weird results
我有一个程序可以加载 jpeg 图像并允许用户在图像上绘图并重新保存。
我正在加载和绘图,但是当我尝试保存图像时,我得到了这个结果
结果应该是带线的蜗牛图像。
这是我的代码
bool IOManager::save_jpg_to_file(const char *file_name) {
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile;
JSAMPROW row_pointer[1];
int row;
JSAMPLE * image_buffer;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if ((outfile = fopen(file_name_.c_str(), "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", file_name_);
return false;
}
jpeg_stdio_dest(&cinfo, outfile);
int img_width = pixel_buffer_->width();
int img_height = pixel_buffer_->height();
cinfo.image_width = img_width;
cinfo.image_height = img_height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE);
jpeg_start_compress(&cinfo, TRUE);
unsigned char bytes[img_width * 3];
while (cinfo.next_scanline < cinfo.image_height) {
for (int i = 0; i < img_width; i+=3){
ColorData colorData = pixel_buffer_->get_pixel(i, cinfo
.next_scanline);
bytes[i] = static_cast<int>(colorData.red()*255) & 0xff;
bytes[i+1] = static_cast<int>(colorData.green()*255) & 0xff;
bytes[i+2] = static_cast<int>(colorData.blue()*255) & 0xff;
}
row_pointer[0] = bytes;
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
std::cout << "Done" << std::endl;
return true;
}
PixelBuffer 只是 RGB 值的二维数组。
我不明白为什么它会生成那些奇怪的线,有什么帮助吗?
只是将我的评论作为单独的答案发布。您似乎以错误的方式访问像素缓冲区数据:您在源缓冲区和目标缓冲区中都跳过了 3 个像素,而(给定您的代码片段)看起来您需要处理 every 来源的像素。确保在迭代 pixel_buffer_
时仅将索引增加 1 而不是 3
我有一个程序可以加载 jpeg 图像并允许用户在图像上绘图并重新保存。
我正在加载和绘图,但是当我尝试保存图像时,我得到了这个结果
结果应该是带线的蜗牛图像。
这是我的代码
bool IOManager::save_jpg_to_file(const char *file_name) {
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile;
JSAMPROW row_pointer[1];
int row;
JSAMPLE * image_buffer;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if ((outfile = fopen(file_name_.c_str(), "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", file_name_);
return false;
}
jpeg_stdio_dest(&cinfo, outfile);
int img_width = pixel_buffer_->width();
int img_height = pixel_buffer_->height();
cinfo.image_width = img_width;
cinfo.image_height = img_height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE);
jpeg_start_compress(&cinfo, TRUE);
unsigned char bytes[img_width * 3];
while (cinfo.next_scanline < cinfo.image_height) {
for (int i = 0; i < img_width; i+=3){
ColorData colorData = pixel_buffer_->get_pixel(i, cinfo
.next_scanline);
bytes[i] = static_cast<int>(colorData.red()*255) & 0xff;
bytes[i+1] = static_cast<int>(colorData.green()*255) & 0xff;
bytes[i+2] = static_cast<int>(colorData.blue()*255) & 0xff;
}
row_pointer[0] = bytes;
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
std::cout << "Done" << std::endl;
return true;
}
PixelBuffer 只是 RGB 值的二维数组。
我不明白为什么它会生成那些奇怪的线,有什么帮助吗?
只是将我的评论作为单独的答案发布。您似乎以错误的方式访问像素缓冲区数据:您在源缓冲区和目标缓冲区中都跳过了 3 个像素,而(给定您的代码片段)看起来您需要处理 every 来源的像素。确保在迭代 pixel_buffer_