【问题标题】:How to load a part of a TIFF image without loading whole image into memory?如何加载 TIFF 图像的一部分而不将整个图像加载到内存中?
【发布时间】:2013-04-24 04:10:55
【问题描述】:

如何加载 *.tif 图像的一部分而不将该图像加载到内存中。

我必须处理大的 TIFF 文件。 (> 4 GB)。我尝试使用BinaryReader 读取此文件,并使用BitMiracle.LibTiff.Classic 将字节转换为图像。但我没有找到如何读取 TIFF 文件中特定像素的示例。

也许您对此任务有一些解决方案。

假设我有一个BigScan.tif 文件,它总是:

Image Compression -  NONE
Pixel Order       -  Interleaved (RGBRGB)
Byte Order        -  IBM PC

我有一些变量:

ImagePart with  User Defined Width
ImagePart with  User Define Height
ImagePArt with  User Defined Location

问题是,我怎样才能从BigScan.tif 得到ImagePart

但最好能够读取带有 (x,y) 坐标的“BigScan.tif”中的像素信息。

我需要从指定位置的BigScan.tif读取一个像素,具有这样的功能:

public Color GetPixelColorFromTiffImage(string TiffFileName, int PixelPositionX, int PixelPositionY)
{
    //Some Code
   return returnedColor;
}

很奇怪,但支持并没有回答我的问题。可能有人知道。为什么要将BitMiracle Samples 中的这部分代码写入“-11512229”、“-11838376”等“光栅”数组编号。

 using (Tiff image = Tiff.Open(fullImageLocation, "r"))
        {

            // Find the width and height of the image
            FieldValue[] value = image.GetField(TiffTag.IMAGEWIDTH);
             width = value[0].ToInt();

            value = image.GetField(TiffTag.IMAGELENGTH);
            height = value[0].ToInt();

            int imageSize = height * width;
            int[] raster = new int[imageSize];


            // Read the image into the memory buffer
            if (!image.ReadRGBAImage(width, height, raster))
            {
                MessageBox.Show("Could not read image");

            }


            using (Bitmap btm = new Bitmap(200, 200))
            {
                for (int i = 0; i < btm.Width; ++i)
                    for (int j = 0; j < btm.Height; ++j)
                        btm.SetPixel(i, j, getSample(i + 330, j + 30, raster, width, height));

                ReternedBitmap = btm;
            }
        }//using    

【问题讨论】:

  • 这有帮助吗? bitmiracle.com/libtiff/help/…
  • 我看到了这个页面。但我仍然想知道它如何提供帮助。如何使用它来设置像素的位置,并从主 tif 文件中读取数据?
  • 它允许您从图像中读取任意数量的刻度 - 因此您至少可以选择一系列行(y 坐标),即使您必须采用全宽(x 坐标) -也许这有帮助?
  • 对不起,我还是不明白。你能用readScinline写一个例子吗,我怎样才能得到坐标(x,y)的像素信息?
  • 嗯,这并不理想,但它比加载整个图像要好 ;-) 由于基于行的压缩选项,我不知道 TIFF 的单像素访问器。

标签: c# tiff libtiff.net


【解决方案1】:

您的问题不清楚(您至少问了两个不同的问题)。

如果您需要裁剪较大图像的一部分,那么您需要:

  1. 读取源图像的​​每个相关扫描线
  2. 将该扫描线的一部分复制到新图像。

如果您需要在给定位置获取单个像素的颜色值,那么您需要:

  1. 阅读相关扫描线
  2. 在该扫描线中查找相关字节
  3. 将这些字节打包到Color 结构或其他任何东西中

您没有为您的图片指定 PhotometricBitsPerSampleSamplesPerPixel 值,因此很难判断您到底在处理什么。

很可能,您面临的是地理图像。如果是这样,它们可能是 RGB、24 位、平铺 图像。

对于平铺图像,一次只能读取图像的一小部分(例如,256 x 256 像素)。但即使它们被剥离,这样一幅图像的一条扫描线也只占用大约 1 MB 的内存(219 000 像素 * 每个像素 3 字节)。如果你真的需要处理这么大的图像,那也没关系。

我不建议您尝试开发自己的解析器。如果您只了解 TIFF 格式的基础知识,这并不容易。

【讨论】:

  • 非常感谢您的回答。你是对的,现在我在编写自己的“开瓶器”时遇到了一些问题,因为事实证明 - 我实际上并不知道文件的指定((。我只是希望 BitMiracle 会有所帮助。你能帮我写代码的一部分?因为 *.tiff 文件对我来说真的很神奇。
猜你喜欢
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 2014-03-28
  • 2014-02-22
  • 2020-06-11
相关资源
最近更新 更多