【问题标题】:libjpeg: decompress & croplibjpeg:解压缩和裁剪
【发布时间】:2012-10-03 16:29:35
【问题描述】:

我有下一个基于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. 中止解压。

但是这段代码是多余的。

【问题讨论】:

  • 它是多余的,但很简单。除非你真的需要更好的东西,否则我会坚持下去。

标签: c++ crop libjpeg


【解决方案1】:

性能方面,特别是如果原始图像是高分辨率并且您需要相对较小的一部分,您可能应该先crop/trim the image losslessly without decompressing it,这可能在 16x16 px (8x8?) 粒度和快速,然后解压缩只跳过边缘的几行和像素。您可能还喜欢这种方法,因为操作使用的内存量较少。

如果您只是剪裁一点,那么开始完全解压的原始计划可能是最好的。这里几乎没有冗余。

【讨论】:

  • 通常 16x16 是你能做的最好的。 8x8 仅在图像被编码而不在色度中进行二次采样时才有可能。
  • 谢谢你的回答,@Roman R。现在我将使用现有的代码,但有趣的是如何在libjpeg 中进行无损裁剪。在当前场景中,我需要超过 50% 的图像宽度和 50% 的图像高度,并且代码将在 Android 操作系统上运行。如您所知,嵌入式系统的内存并不多。
  • @artyom.stv,因为 libjpeg 一次读取一行,读取完整图像大小的内存开销可以忽略不计。读取图像时,您将立即丢弃裁剪区域周围的字节。
猜你喜欢
  • 2020-07-28
  • 2012-01-10
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 2015-01-21
  • 2017-06-18
  • 1970-01-01
相关资源
最近更新 更多