2011-05-19 58 views
5

Creé un servicio de ventana para poner todos mis archivos TIFF en la base de datos y los almacené como Byte[].Cómo mostrar TIFF (en forma de Byte []) en Silverlight Control de imagen

Ahora quiero ser capaz de mostrar a través de Silverlight Control de la imagen

lo que el uso del convertidor durante XAML vinculante con el fin de convertir el Byte[] a Bitmap porque el Image.Source sólo aceptan eitheir URI (no tengo el archivo almacenado en el servidor no puede usar este método) o Bitmap.

BitmapImage bmi = new BitmapImage(); 
if (value != null) 
{ 
    ImageGallery imageGallery = value as ImageGallery; 
    byte[] imageContent = imageGallery.ImageContent; 
    string imageType = imageGallery.ImageType; 
    using (MemoryStream ms = new MemoryStream(imageContent)) 
    { 
     bmi.SetSource(ms); 
    } 
} 
return bmi; 

Sin embargo, me sale la excepción bmi.SetSource(ms) porque Silverlight sólo es compatible con imágenes JPEG y PNG.

Así que hice más investigación y sabía que debería convertir los bytes de TIFF a bytes de JPEG o PNG, entonces funcionará.

para hacer eso probé dos métodos:

  • hacer la conversión en el servidor: en mi llamada de servicio RIA, después de recuperar la ImageGallery, yo bucle a través de la imagen disponibles para convertir los bytes de TIFF a los bytes de JPEG.

PERO NO FUNCIONA .... ¿Puede decirme dónde hice mal?

public IQueryable<ImageGallery> GetImageGalleries() 
{ 
    var imageGalleries = this.ObjectContext.ImageGalleries.OrderBy(i=>i.ImageName); 
    foreach (ImageGallery imageGallery in imageGalleries) 
    { 
     if (imageGallery.ImageType == ".tif" || imageGallery.ImageType == ".tiff") 
     { 
      //Convert the Tiff byte array format into JPEG stream format 
      System.Drawing.Bitmap dImg = new System.Drawing.Bitmap(new MemoryStream(imageGallery.ImageContent)); 
      MemoryStream ms = new MemoryStream(); 
      dImg.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 

      //then convert the JPEG stream format into JPEG byte array format 
      byte[] buf = new byte[ms.Length]; 
      ms.Read(buf, 0, buf.Length); 

      //Changing the format tiff byte[] of ImageGallery to jpeg byte[] 
      imageGallery.ImageContent = buf; 
     } 
    } 
    return imageGalleries; 
} 
  • La otra solución es utilizar LibTiff.Net biblioteca para convertir directamente la Byte[] de TIFF a WritableBitmap directamente en Silverlight.

Sin embargo, después de cavar a través de su aplicación de la muestra o el uso de reflector para ver las funciones de código fuente, todavía no puedo encontrar la manera de utilizar la biblioteca para convertir los bytes de TIFF a WritableBitmap JPEG (o PNG), porque su muestra solo muestra la API para usar la búsqueda TIFF en un directorio de archivos. En mi caso, no tengo un archivo existente en el servidor.

¿Alguien me puede ayudar a mostrar el archivo TIFF en el control de imagen de Silverlight?

Busqué en el foro pero no encontré ninguna respuesta sólida para esto.

gracias

Respuesta

2

creo que el libtiff será el camino a seguir. Ulitmately el Tiff.ClientData acepta un Stream que es la información tiff. Si sus datos de tiff realmente son byte[], entonces solo necesita un MemoryStream alrededor. Es más probable que en algún momento el byte[] se extraiga de una secuencia, por lo que probablemente ni siquiera necesite este intermetario byte[]/MemoryStream.

2
  1. Referencia LibTiff.neta

  2. Añadir esta clase:

    using System; 
    using System.Collections.Generic; 
    using System.IO; 
    using System.Windows.Media.Imaging; 
    using BitMiracle.LibTiff.Classic; 
    
    namespace CoreTechs.X9 
    { 
        public static class TiffUtility 
        { 
         public static Tiff CreateTiff(this byte[] bytes) 
         { 
          MemoryStream ms = new MemoryStream(bytes); 
          Tiff tiff = Tiff.ClientOpen("in-memory", "r", ms, new TiffStream()); 
          return tiff; 
         } 
    
         public static IEnumerable<WriteableBitmap> ConvertToWriteableBitmaps(this Tiff tiff) 
         { 
          if (tiff == null) 
           throw new ArgumentNullException("tiff", "tiff is null."); 
    
          short dirs = tiff.NumberOfDirectories(); 
    
          for (int i = 0; i < dirs; i++) 
          { 
           if (tiff.SetDirectory((short)i)) 
           { 
            int tileCount = tiff.NumberOfTiles(); 
            int stripCount = tiff.NumberOfStrips(); 
    
            var frameWidthField = tiff.GetField(TiffTag.IMAGEWIDTH); 
            var frameHeightField = tiff.GetField(TiffTag.IMAGELENGTH); 
            var compressionField = tiff.GetField(TiffTag.COMPRESSION); 
            var xResolutionField = tiff.GetField(TiffTag.XRESOLUTION); 
            var yResolutionField = tiff.GetField(TiffTag.YRESOLUTION); 
            var samplesPerPixelField = tiff.GetField(TiffTag.SAMPLESPERPIXEL); 
    
            int frameWidth = frameWidthField != null && frameWidthField.Length > 0 ? frameWidthField[0].ToInt() : 0; 
            int frameHeight = frameHeightField != null && frameHeightField.Length > 0 ? frameHeightField[0].ToInt() : 0; 
            var compression = compressionField != null && compressionField.Length > 0 ? (Compression)compressionField[0].Value : Compression.NONE; 
            var xResolution = xResolutionField != null && xResolutionField.Length > 0 ? new double?(xResolutionField[0].ToDouble()) : null; 
            var yResolution = yResolutionField != null && yResolutionField.Length > 0 ? new double?(yResolutionField[0].ToDouble()) : null; 
            var samplesPerPixel = samplesPerPixelField != null && samplesPerPixelField.Length > 0 ? samplesPerPixelField[0].ToString() : String.Empty; 
    
            if (xResolution != null && yResolution == null) 
            { 
             yResolution = xResolution; 
            } 
    
            var buffer = new int[frameWidth * frameHeight]; 
            tiff.ReadRGBAImage(frameWidth, frameHeight, buffer); 
    
            var bmp = new WriteableBitmap(frameWidth, frameHeight); 
            for (int y = 0; y < frameHeight; y++) 
            { 
             var ytif = y * frameWidth; 
             var ybmp = (frameHeight - y - 1) * frameWidth; 
    
             for (int x = 0; x < frameWidth; x++) 
             { 
              var currentValue = buffer[ytif + x]; 
    
              // Shift the Tiff's RGBA format to the Silverlight WriteableBitmap's ARGB format 
              bmp.Pixels[ybmp + x] = Tiff.GetB(currentValue) | Tiff.GetG(currentValue) << 8 | Tiff.GetR(currentValue) << 16 | Tiff.GetA(currentValue) << 24; 
             } 
            } 
    
            yield return bmp; 
           } 
          } 
         } 
        } 
    } 
    
  3. utilizar los métodos exension como este:

    byte[] myHappyTiffData = GetMyTiffBytesFromSomewhere(); 
    WriteableBitmap bmp = myHappyTiffData.CreateTiff().ConvertToWriteableBitmaps().FirstOrDefault(); 
    myImageControl.Source = bmp; 
    
1

Comenzamos con libtiff como una solución para nuestro gestor de medios de comunicación. No lo recomendaría.

Como puede ver, crea un WriteableBitmap para cada página. WB es el objeto que más obstaculiza el desempeño y puede fugarse en Silverlight, por lo que si tienes más de 1 tiff de una sola página, tu aplicación se quedará sin memoria más rápido que Avada Kedavra.

Hay espectadores que aparentemente pueden cargar un tiff multipágina grande sin matar tu aplicación (y el navegador y la computadora), por una licencia decente, pero en este punto no tengo nada que te permita descifrar un tiff un extracto de las páginas .

finalistas:

Cuestiones relacionadas