2011-05-19 1 views
5

J'ai créé un service de fenêtre pour mettre tous mes fichiers TIFF dans la base de données et de les stockées sous forme Byte[].Comment afficher TIFF (sous forme d'octet []) sur le contrôle de l'image Silverlight

Maintenant, je veux être en mesure de les afficher par le contrôle de l'image Silverlight

donc j'utiliser le convertisseur pendant la liaison XAML afin de convertir le Byte[] à Bitmap parce que le Image.Source acceptent que eitheir URI (Je n'ai pas le fichier stocké sur le serveur ne peut donc pas utiliser cette méthode) ou 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; 

Cependant, je reçois l'exception à bmi.SetSource(ms) parce que Silverlight ne supporte que les images JPEG et PNG.

J'ai donc fait plus de recherches et savaient que je devrais convertir les octets de TIFF en octets de JPEG ou PNG, alors il fonctionnera.

Pour ce faire, j'ai essayé deux méthodes:

  • Faire la conversion sur le serveur: dans mon RIA appel de service, après avoir récupéré la ImageGallery, je boucle à travers l'image disponible pour convertir les octets de TIFF aux octets de JPEG.

MAIS CELA NE FONCTIONNE PAS .... Pouvez-vous me dire où j'ai mal fait?

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; 
} 
  • L'autre solution consiste à utiliser LibTiff.Net bibliothèque pour convertir directement la Byte[] de TIFF à WritableBitmap directement sur Silverlight.

Cependant, après avoir creusé par leur exemple d'application ou à l'aide réflecteur pour voir les fonctions de code source, je ne peux toujours pas comprendre comment utiliser leur bibliothèque pour convertir les octets de TIFF à WritableBitmap JPEG (ou PNG) parce que leur exemple montre seulement l'API pour utiliser la recherche du TIFF dans un répertoire de fichiers. Dans mon cas, je n'ai pas de fichier existant sur le serveur.

quelqu'un peut me aider comment afficher le fichier TIFF sur le contrôle de l'image de Silverlight?

J'ai cherché le forum, mais n'a pas trouvé de réponse solide pour cela.

grâce

Répondre

2

je pense que le LibTIFF sera le chemin à parcourir. Ultimement le Tiff.ClientData accepte un Stream qui est les données tiff. Si vos données tiff sont vraiment un byte[] alors vous avez juste besoin d'un MemoryStream autour d'elle. Plus probablement à un certain point, le byte[] est tiré d'un flux de sorte que vous n'avez probablement même pas besoin de cet intermédiaire byte[]/MemoryStream.

2
  1. Référence LibTIFF.net

  2. Ajouter cette classe:

    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. Utilisez les méthodes de exension comme celui-ci:

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

Nous avons commencé par LibTIFF comme une solution pour notre gestionnaire de médias. Je ne le recommanderais pas.

Comme vous pouvez le voir, il crée un WriteableBitmap pour chaque page. WB est l'objet qui fuit le plus les performances, vous pouvez utiliser dans Silverlight, donc si vous avez plus d'une page tiff votre application va manquer de mémoire plus vite, vous pouvez dire Avada Kedavra. Il ya des téléspectateurs qui peuvent apparemment charger un gros tiff multipage sans tuer votre application (et votre navigateur et votre ordinateur), pour un prix de licence décent, mais à ce stade, je n'ai rien qui vous permet de décoder un tiff et d'extraire les pages .

Runner up:

Questions connexes