从 SVS 文件中提取全尺寸图像

Extract a full-scale image from a SVS file

我正在尝试使用 Libtiff 提取 SVS 文件的第一页。 SVS 文件对此图像使用 JPEG2000 压缩。

我的计划是:

  1. 从 SVS 的第一页提取原始图块,并且
  2. 使用 OpenJPEG 对其进行解码。

下面是我尝试从 SVS 中提取原始图块的内容。我只从 152MB 的 svs 文件中得到了一个 43KB 的输出文件(它未能提取原始图块)。

我希望有人能告诉我如何从 SVS 文件中提取图块。

int main()
{
    const char* filename = "input.svs";
    TIFF* tiff_in = TIFFOpen(filename, "r");
    TIFF* tiff_out = TIFFOpen("output.raw", "w");
    if (tiff_in) {
        uint32 imageWidth, imageLength;
        uint32 tileWidth, tileLength;
        uint32 tileCount, tileByteCounts;
        uint32 samplePerPixel, bitsPerSample;
        uint32 orientation, planarConfig, photoMetric;
        uint32 xResolution, yResolution;
        uint32 x, y;
        ttile_t tile;
        // get fileds from the input file
        TIFFGetField(tiff_in, TIFFTAG_IMAGEWIDTH, &imageWidth);
        TIFFGetField(tiff_in, TIFFTAG_IMAGELENGTH, &imageLength);
        TIFFGetField(tiff_in, TIFFTAG_TILEWIDTH, &tileWidth);
        TIFFGetField(tiff_in, TIFFTAG_TILELENGTH, &tileLength);
        TIFFGetField(tiff_in, TIFFTAG_SAMPLESPERPIXEL, &samplePerPixel);
        TIFFGetField(tiff_in, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
        TIFFGetField(tiff_in, TIFFTAG_TILEBYTECOUNTS, &tileByteCounts);
        TIFFGetField(tiff_in, TIFFTAG_ORIENTATION, &orientation);
        TIFFGetField(tiff_in, TIFFTAG_PLANARCONFIG, &planarConfig);
        TIFFGetField(tiff_in, TIFFTAG_PHOTOMETRIC, &photoMetric);
        TIFFGetField(tiff_in, TIFFTAG_XRESOLUTION, &xResolution);
        TIFFGetField(tiff_in, TIFFTAG_YRESOLUTION, &yResolution);

        // set files to the output file
        TIFFSetField(tiff_out, TIFFTAG_IMAGEWIDTH, imageWidth);
        TIFFSetField(tiff_out, TIFFTAG_IMAGELENGTH, imageLength);
        TIFFSetField(tiff_out, TIFFTAG_TILEWIDTH, tileWidth);
        TIFFSetField(tiff_out, TIFFTAG_TILELENGTH, tileLength);
        TIFFSetField(tiff_out, TIFFTAG_SAMPLESPERPIXEL, samplePerPixel);
        TIFFSetField(tiff_out, TIFFTAG_BITSPERSAMPLE, bitsPerSample);
        TIFFSetField(tiff_out, TIFFTAG_PLANARCONFIG, planarConfig);
        TIFFSetField(tiff_out, TIFFTAG_PHOTOMETRIC, photoMetric);
        TIFFSetField(tiff_out, TIFFTAG_XRESOLUTION, xResolution);
        TIFFSetField(tiff_out, TIFFTAG_YRESOLUTION, yResolution);
        //TIFFSetField(tiff_out, TIFFTAG_ROWSPERSTRIP, 1);

        tdata_t buf = _TIFFmalloc(TIFFTileSize(tiff_in));
        for (int tile = 0; tile < TIFFNumberOfTiles(tiff_in); tile++)
        {
            TIFFReadRawTile(tiff_in, tile, buf, (tsize_t)-1);
            TIFFWriteRawTile(tiff_out, tile, buf, (tsize_t)sizeof(buf));
        }
        _TIFFfree(buf);
        TIFFClose(tiff_in);
        TIFFClose(tiff_out);
    }
    return 0;
}

您正在编写每个 8 字节的磁贴。 sizeof(buf) 是指针 buf 的字节大小。您想使用实际读取的字节数,即 return 由 TIFFReadRawTile:

编辑
tsize_t size = TIFFReadRawTile(tiff_in, tile, buf, (tsize_t)-1);
TIFFWriteRawTile(tiff_out, tile, buf, size);

请注意,您在这里将 JPEG2000 压缩数据复制到输出文件。您必须使用 OpenJPEG 解压缩此数据,然后写入未压缩图块大小的数据,在连续平面配置中为 tileWidth * tileLength * samplePerPixel * bitsPerSample / 8,在单独平面配置中为 tileWidth * tileLength * bitsPerSample / 8


使用TIFFGetFieldTIFFSetField时,您需要检查return值。如果发生错误,则 return 为 0。您不能依赖未正确读取的值。

其他错误和警告通常打印到 stderr。如果您在 Windows 下开发,这些通常不会显示。我建议你看看TIFFSetErrorHandler and TIFFSetWarningHandler,在这里设置合适的消息显示功能对你的开发有很大的帮助。