libjpeg:解压缩和裁剪

3

我有一段基于libjpeg的标准代码,用于JPEG图像解压。

jpeg_decompress_struct cinfo;
// ...Set error manager and data source...
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
while (cinfo.output_scanline < cinfo.output_height) {
    JSAMPLE* scanlines[1];
    // ...Set target pointer for scanline...
    jpeg_read_scanlines(&cinfo, scanlines, 1);
}
jpeg_destroy_decompress(&cinfo);

我想读取由矩形裁剪的图像部分:

// struct RECT {
//     int left;
//     int top;
//     int right;
//     int bottom;
// };
RECT cropRect; // Coordinates of the crop rectangle relative to the output image size

下面的代码中,我应该修改什么以告诉libjpeg立即裁剪图像?
以下是我可以实现它的方法:
  1. 忽略前top - 1行;
  2. 对于接下来的每个bottom - top行: 1)将扫描线读入临时缓冲区; 2)从临时缓冲区中的列范围[left, right)复制像素到目标缓冲区。
  3. 终止解压缩。
但这段代码是多余的。

这很冗余但很简单。除非你真的需要更好的东西,否则我建议你坚持使用它。 - Mark Ransom
1个回答

2
就性能而言,特别是如果原始图像具有高分辨率,并且您只需要其中的一小部分,则应该先无损地裁剪/修剪图像,这可以在16x16像素(8x8?)的粒度下快速进行,然后跳过一些边缘的行和像素进行解压缩。对于使用较少内存的操作,您可能也会喜欢这种方法。
如果您只是稍微裁剪一下,则最初的计划以完整方式开始解压缩可能是最好的。这里几乎没有冗余。

1
通常情况下,16x16是你能做到的最好的。只有当图像在色度上没有进行子采样编码时,才可能使用8x8。 - Mark Ransom
感谢您的答复,@Roman R。目前我将使用现有代码,但是如何在libjpeg中进行无损裁剪很有趣。在当前情况下,我需要图像宽度的50%和图像高度的50%以上,并且该代码将在Android操作系统上运行。如您所知,嵌入式系统上的内存并不多。 - artyom.stv
@artyom.stv,由于libjpeg一次只读取一行,因此读取完整图像大小的内存开销可以忽略不计。当读取图像时,您将立即丢弃裁剪区域周围的字节。 - Mark Ransom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接