读取 JPEG,调整大小并将其保存到磁盘
Read in JPEG, resize it and save it to disk
我想要的:
将现有的 jpeg 调整为一个新的、更小的 jpeg。
示例:before_3000x2000.jpeg →→→ after_1024x768.jpeg
我想我需要这样的伪函数:
foo( before_file_path, after_file_path, new_width, new_height )
利用了
decompress_jpeg( before_file_path )
resize( decompressed_data, new_width, new_height )
compress_jpeg( resized_data )
save_jpeg( compressed_data, after_file_path )
如果我理解有误,请指正我的方法。
我假设:
- 由于分辨率会有所不同,首先您必须解压缩现有的 jpeg,以便您可以正确处理像素数据。
- 其次,您使用某些函数 foo() 将像素数据调整为较小的缓冲区。
- 第三,压缩缓冲区并将其保存到磁盘。
我尝试过的(但失败了):
首先,我尝试使用
write_JPEG_file (char * filename, int quality)
函数在example.c中提供jpeglib-9b。我只想以我指定的任何分辨率用单一颜色写出一张测试图片。但是我运行遇到了问题。我认为我正在写出随机内存,我不知道为什么。 (这里有一张图片:img_100x100)请注意顶部的某个点是白色的。这部分会根据我在第一个循环中分配的内容进行相应更改。但在一定数量后,它会变成随机噪声。 为什么?
我改变了什么:
我定义了image_width, image_height, image_buffer
我用 fopen_s(...)
.
替换了所有 fopen(...)
我在 jpeg_set_quality(...)
中将质量硬编码为 100
代码:
#include <iostream>
#include "jpeg-9b\jpeglib.h"
#include "jpeg-9b\jerror.h"
int TEST_WRITE_JPEG(char* file_name)
{
// DEFINE A PIC HERE
const int image_width = 100; /* Number of columns in image */
const int image_height = 100; /* Number of rows in image */
JSAMPLE* image_buffer = new JSAMPLE[image_width * image_height](); /* Points to large array of R,G,B-order data */
for (int i = 0; i < image_width*image_height; i++)
{
image_buffer[i] = 255;
}
/* Step 1: allocate and initialize JPEG compression object */
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile;
JSAMPROW row_pointer[1];
int row_stride;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
/* Step 2: specify data destination (eg, a file) */
if (fopen_s(&outfile, file_name, "wb") != NULL)
{
fprintf(stderr, "can't open %s\n", file_name);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
/* Step 3: set parameters for compression */
cinfo.image_width = image_width; /* image width and height, in pixels */
cinfo.image_height = image_height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE);
/* Step 4: Start compressor */
jpeg_start_compress(&cinfo, TRUE);
/* Step 5: while (scan lines remain to be written) */
row_stride = image_width * 3;
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = (JSAMPROW)&image_buffer[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
/* After finish_compress, we can close the output file. */
fclose(outfile);
/* Step 7: release JPEG compression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_compress(&cinfo);
return 0;
}
明确问题:
为什么我写出 this 图片而不是纯白色的?
如果 image_buffer
包含超过 128x128 个无符号字符,为什么程序会崩溃?
每个像素使用 3 个字节,因此您必须分配 3 * image_width * image_height
个元素,而您只分配 image_width * image_height
个元素。分配并初始化足够的元素。
我想要的:
将现有的 jpeg 调整为一个新的、更小的 jpeg。
示例:before_3000x2000.jpeg →→→ after_1024x768.jpeg
我想我需要这样的伪函数:
foo( before_file_path, after_file_path, new_width, new_height )
利用了
decompress_jpeg( before_file_path )
resize( decompressed_data, new_width, new_height )
compress_jpeg( resized_data )
save_jpeg( compressed_data, after_file_path )
如果我理解有误,请指正我的方法。
我假设:
- 由于分辨率会有所不同,首先您必须解压缩现有的 jpeg,以便您可以正确处理像素数据。
- 其次,您使用某些函数 foo() 将像素数据调整为较小的缓冲区。
- 第三,压缩缓冲区并将其保存到磁盘。
我尝试过的(但失败了):
首先,我尝试使用
write_JPEG_file (char * filename, int quality)
函数在example.c中提供jpeglib-9b。我只想以我指定的任何分辨率用单一颜色写出一张测试图片。但是我运行遇到了问题。我认为我正在写出随机内存,我不知道为什么。 (这里有一张图片:img_100x100)请注意顶部的某个点是白色的。这部分会根据我在第一个循环中分配的内容进行相应更改。但在一定数量后,它会变成随机噪声。 为什么?
我改变了什么:
我定义了image_width, image_height, image_buffer
我用 fopen_s(...)
.
替换了所有 fopen(...)
我在 jpeg_set_quality(...)
代码:
#include <iostream>
#include "jpeg-9b\jpeglib.h"
#include "jpeg-9b\jerror.h"
int TEST_WRITE_JPEG(char* file_name)
{
// DEFINE A PIC HERE
const int image_width = 100; /* Number of columns in image */
const int image_height = 100; /* Number of rows in image */
JSAMPLE* image_buffer = new JSAMPLE[image_width * image_height](); /* Points to large array of R,G,B-order data */
for (int i = 0; i < image_width*image_height; i++)
{
image_buffer[i] = 255;
}
/* Step 1: allocate and initialize JPEG compression object */
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile;
JSAMPROW row_pointer[1];
int row_stride;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
/* Step 2: specify data destination (eg, a file) */
if (fopen_s(&outfile, file_name, "wb") != NULL)
{
fprintf(stderr, "can't open %s\n", file_name);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
/* Step 3: set parameters for compression */
cinfo.image_width = image_width; /* image width and height, in pixels */
cinfo.image_height = image_height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, TRUE);
/* Step 4: Start compressor */
jpeg_start_compress(&cinfo, TRUE);
/* Step 5: while (scan lines remain to be written) */
row_stride = image_width * 3;
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = (JSAMPROW)&image_buffer[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
/* Step 6: Finish compression */
jpeg_finish_compress(&cinfo);
/* After finish_compress, we can close the output file. */
fclose(outfile);
/* Step 7: release JPEG compression object */
/* This is an important step since it will release a good deal of memory. */
jpeg_destroy_compress(&cinfo);
return 0;
}
明确问题:
为什么我写出 this 图片而不是纯白色的?
如果 image_buffer
包含超过 128x128 个无符号字符,为什么程序会崩溃?
每个像素使用 3 个字节,因此您必须分配 3 * image_width * image_height
个元素,而您只分配 image_width * image_height
个元素。分配并初始化足够的元素。