2011-05-19 101 views
5

我創建了一個窗口服務,將所有TIFF文件放入數據庫並將它們存儲爲Byte[]如何在Silverlight圖像控件上顯示TIFF(以字節[]的形式)

現在我希望能夠通過Silverlight的圖像控制

所以我用的轉換器,以便結合XAML中的Byte[]轉換爲Bitmap,因爲Image.Source只接受eitheir URI來顯示他們(我沒有存儲在服務器上的文件因此不能使用此方法)或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; 

但是,由於Silverlight僅支持JPEG和PNG圖像,因此我在bmi.SetSource(ms)處得到例外。

所以我做了更多的研究,並知道我應該將TIFF的字節轉換爲JPEG或PNG的字節,然後才能工作。

這樣做,我嘗試了兩種方法:

  • 做服務器上的轉換:在我的RIA服務調用,檢索ImageGallery後,我遍歷可用的圖像以TIFF的字節轉換爲字節的JPEG。

但是它不工作.... 你能告訴我我做錯了嗎?

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; 
} 
  • 另一個解決方案是使用LibTiff.Net庫直接TIFF的Byte[]轉換爲WritableBitmap直接的Silverlight。

然而,通過他們的示例應用程序挖掘或使用反射來看看源代碼的功能後,我仍然無法弄清楚如何使用他們的庫TIFF的字節轉換爲WritableBitmap JPEG(或PNG),因爲他們的示例僅顯示在文件目錄中使用搜索TIFF的API。就我而言,我沒有在服務器上存在的文件。

有人可以幫助我如何在Silverlight的Image控件上顯示TIFF文件?

我搜索了論壇,但沒有找到任何可靠的答案。

感謝

回答

2

我想的libtiff將要走的路。 Ulitmately Tiff.ClientData接受Stream即tiff數據。如果你的tiff數據真的是byte[],那麼你只需要圍繞它MemoryStream。更有可能在某一時刻,byte[]被從流中拉出,因此您可能甚至不需要這種介入性的byte[]/MemoryStream

2
  1. Reference LibTiff。淨

  2. 加入這個類:

    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. 使用exension方法是這樣的:

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

我們開始利用libtiff爲我們的媒體管理器解決方案。我不會推薦它。

正如你所看到的,它爲每個頁面創建一個WriteableBitmap。 WB是在Silverlight中可以使用的性能最差,泄漏的對象,所以如果您獲得了更多的單頁Tiff,那麼您的應用程序將會更快耗盡內存,然後您可以說Avada Kedavra。

有觀衆顯然可以加載一個大的多頁TIFF而不會殺死你的應用程序(以及瀏覽器和計算機),但是在這一點上我沒有任何東西可以讓你解碼TIFF並提取頁面。

亞軍:

相關問題