简体   繁体   中英

How to load a part of a TIFF image without loading whole image into memory?

How to load a part of a *.tif image without loading this image into memory.

I have to work with big TIFF files. (> 4 GB). I tried to read this file using BinaryReader , and using BitMiracle.LibTiff.Classic to convert bytes into image. But I didn't find example for how to read a specific pixel in a TIFF file.

Maybe be you have some solution for this task.

Lets say i have a BigScan.tif file and it is always:

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

I have some variable:

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

The question is, how could I get ImagePart from BigScan.tif ?

But it would be best to have the ability to read information of the pixel in "BigScan.tif" with (x,y) coorinates.

I need to read a pixel from the BigScan.tif in specified place, with such function:

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

Very strange but the support did`t unswer my quastion. May be somebody knows it. Why dose this part of the code from BitMiracle Samples wrote to 'raster' array numbers like "-11512229", "-11838376" and so on.

 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    

Your question is unclear (you ask at least two different questions).

If you need to crop a part of a larger image then you need to:

  1. read each relevant scanline of a source image
  2. copy part of that scanline to a new image.

If you need to get color value of a single pixel in a given location than again you need to:

  1. read relevant scanline
  2. find relevant bytes in that scanline
  3. pack those bytes into a Color structure or whatever else

You didn't specify what are Photometric , BitsPerSample and SamplesPerPixel values for your image, so it's hard to tell what exactly are you dealing with.

Most probably, you are faced with geo-images. If so, they are probably RGB, 24bit, tiled images.

For tiled images it is possible to read only small part (say, 256 x 256 pixels) of the image at once. But even if they are stripped, one scanline of such an image will take only about 1 MB of memory (219 000 pixels * 3 bytes per pixel). It's nothing if you are really need to process such big images.

I wouldn't recommend you to try developing your own parser. It's not that easy if you know only basics about TIFF format.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM