2012-01-25 7 views
13

Estoy buscando una biblioteca que pueda abrir y copiar secciones de un archivo TIFF grande. Miré LibTiff.Net, que abre el archivo muy rápidamente pero no tiene ninguna función para recortar o copiar secciones de la imagen. Mi imagen es de 100.000 x 100.000 píxeles hacia arriba y la creación de un System.Drawing.Bitmap de ese tamaño bloquea la aplicación, por lo que la conversión a un Bitmap primero no es una opción.Abre TIF enorme en .NET y copia partes en la nueva imagen

¿Alguien puede recomendar una biblioteca .NET?

+0

Oh, Señor, eso es 40 * gigabytes *. ¿Supongo que solo tienes un sistema operativo de 32 bits para hacerlo más desafiante? –

+0

Estoy ejecutando hardware de 64 bits, pero la lectura desde el disco será la forma ideal de procesarlo. Estoy profundizando en LibTiff.Net que tiene funciones para leer scanline, que puede ser lo que necesito – JWood

+0

¿El color de la imagen es escala de grises o binivel? Para binivel tengo una solución de código nativo que puede resolver el problema de memoria. Envíame un correo electrónico ([email protected]). – BitBank

Respuesta

5

Si su archivo es menos de 4 GB en el disco que le recomiendo que eche un vistazo a LibTiff.Net. Incluso con imágenes tan grandes tienes algunas opciones.

Antes que nada, compruebe si su imagen está embaldosada o despojada. El método Tiff.IsTiled le dará la respuesta.

Si su imagen está en mosaico, entonces probablemente no la lea con el método ReadScanline. Podría ser mejor usar el método ReadEncodedTile en ese caso.

Si se quitan las imágenes, entonces puede usar los métodos ReadScanline y ReadEncodedStrip para leerlo.

Si desea utilizar algo que espera System.Drawing.Bitmap, intente utilizar ReadRGBATile o ReadRGBAStrip. Estos métodos se pueden usar para crear mapas de bits a partir de partes de su imagen. No hay muestra para esto, pero Convert color TIFF to a 32-bit System.Drawing.Bitmap debería darle casi toda la información requerida acerca de cómo convertir mosaico o tira de una imagen en un mapa de bits.

EDIT:

LibTiff.Net 2.4.508 añade soporte para BigTiff así también están soportados archivos de más de 4GB.

+0

Tengo una imagen en mosaico que está comprimida en JPG. Quiero acceder a la imagen y volver a escribirla. ¿Leo con ReadEncodedTile y escribo con WriteTile o WriteEncodedTile? – Krip

+0

Lo tengo trabajando con ReadEncodedTile seguido de WriteEncodedTile. – Krip

4

Su imagen debe estar en formato BigTIFF, ya que el TIFF normal no puede superar los 4 GB.

BigTIFF se puede leer con una versión modificada de libtiff (disponible en BigTIFF website), esta biblioteca permite manejar tales imágenes de la manera que desee sin cargar todos los datos de píxeles en la memoria.

No vi enlaces para .NET pero no debería ser demasiado largo para hacerlo.

0

Atalasoft dotImage tiene esta capacidad incorporada en el decodificador TIFF. El decodificador implementa la interfaz IRegionReadable, que le permite leer una sección rectangular de una página determinada de una imagen en un Stream.

En un TIFF, esta sección respetará la etiqueta de orientación y en tiffs pelados o en mosaico utiliza el conjunto mínimo de mosaicos y tiras para rellenar el rectángulo.

(descargo de responsabilidad, trabajo para Atalasoft y escribió que la interfaz y la implementó en el decodificador TIFF)

+0

¿Es posible con dotImage abrir archivos TIFF usando un factor de escala, digamos 1/2 o 1/4? Entonces, ¿para generar miniaturas rápidamente para archivos TIFF grandes? ¿Qué tan rápido puedo actualizar metadatos de archivos TIFF grandes? –

+0

Esto no es posible en el caso general debido a las complicaciones del mosaico y la orientación de la imagen. Sin embargo, tenemos en cuenta la mayoría de estos cuando implementamos la interfaz IScaledDecoder para permitir que las imágenes se lean a escala, por lo que, aunque el peor de los casos no cambia, se respetan los mejores casos. En cuanto a la actualización de metadatos, ¿qué es más rápido para ti? Este es un proceso enlazado IO. Parece que funciona tan bien como esperaba. – plinth

+0

Por favor, infórmeme cuándo agregará esta capacidad. Esta es la única razón por la que puedo cambiar de mi biblioteca actual de procesamiento TIFF a otra. –

0

Como se mencionó Bobrovsky debe comprobar si su imagen de archivo es de baldosas o no. A continuación, presenté el código de fragmento para leer un tiff de flujo y recortar la parte superior izquierda de la imagen.

using (Tiff input = Tiff.Open(@"imageFile.tif", "r")) 
     { 
      // get properties to use in writing output image file 
      int width = input.GetField(TiffTag.IMAGEWIDTH)[0].ToInt(); 
      int height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt(); 
      int samplesPerPixel = input.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt(); 
      int bitsPerSample = input.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt(); 
      int photo = input.GetField(TiffTag.PHOTOMETRIC)[0].ToInt(); 

      int scanlineSize = input.ScanlineSize();  
      byte[][] buffer = new byte[height][]; 
      for (int i = 0; i < height; ++i) 
      { 
       buffer[i] = new byte[scanlineSize]; 
       input.ReadScanline(buffer[i], i); 
      } 



      using (Tiff output = Tiff.Open("splitedImage.tif", "w")) 
      { 
       output.SetField(TiffTag.SAMPLESPERPIXEL, samplesPerPixel); 
       output.SetField(TiffTag.IMAGEWIDTH, width/2); 
       output.SetField(TiffTag.IMAGELENGTH, height/2); 
       output.SetField(TiffTag.BITSPERSAMPLE, bitsPerSample); 
       output.SetField(TiffTag.ROWSPERSTRIP, output.DefaultStripSize(0)); 
       output.SetField(TiffTag.PHOTOMETRIC, photo); 
       output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); 


       int c = 0; 
       byte[][] holder = new byte[height][]; 

       for (int i = height/2; i < height; i++) 
       //for (int j = 0; j < height/2 ; j++) 
       { 
        holder[i] = buffer[i].Skip(buffer[i].Length/2).ToArray(); 

        output.WriteScanline(holder[i], c); 
        c++; 
       } 
      } 
     } 

     System.Diagnostics.Process.Start("splitedImage.tif"); 

Para otras partes de la imagen, puede cambiar el rango de "i" en el ciclo.

Cuestiones relacionadas