如何显示TIFF(以字节[]的形式)对Silverlight的图像控制 [英] How to display TIFF (in form of Byte[]) on Silverlight Image control

查看:485
本文介绍了如何显示TIFF(以字节[]的形式)对Silverlight的图像控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个窗口服务,把我所有的TIFF文件到数据库并保存他们为字节[]

现在我希望能够通过Silverlight的Image控件来显示它们

所以,我在为了转换字节[] 位图,因为<绑定XAML使用转换器code> Image.Source 只接受eitheir URI(我没有保存在服务器,因此不能使用此方法的文件)或者位图

 的BitmapImage BMI =新的BitmapImage();
如果(值!= NULL)
{
    ImageGallery imageGallery =价值ImageGallery;
    byte []的imageContent = imageGallery.ImageContent;
    字符串IMAGETYPE = imageGallery.ImageType;
    使用(MemoryStream的毫秒=新的MemoryStream(imageContent))
    {
        bmi.SetSource(毫秒);
    }
}
返回BMI;
 

不过,我得到的异常在 bmi.SetSource(MS),因为Silverlight的只支持JPEG和PNG图像。

所以,我没有更多的研究,知道我应该TIFF的字节转换为JPEG或PNG字节,然后它会工作。

要做到这一点我试过两种方法:

  • 在做服务器的转换:在我的RIA服务电话,通过可用的图像检索 ImageGallery ,我循环后,TIFF的字节转换为JPEG的字节

但它没有工作.... 你能告诉我在哪儿做错了?

 公开的IQueryable&LT; ImageGallery&GT; GetImageGalleries()
{
    VAR imageGalleries = this.ObjectContext.ImageGalleries.OrderBy(I =&GT; i.ImageName);
    的foreach(在imageGalleries ImageGallery imageGallery)
    {
        如果(imageGallery.ImageType ==。TIF|| imageGallery.ImageType ==.TIFF)
        {
            //为TIFF字节数组格式转换成JPEG流格式
            System.Drawing.Bitmap dImg =新System.Drawing.Bitmap(新的MemoryStream(imageGallery.ImageContent));
            MemoryStream的毫秒=新的MemoryStream();
            dImg.Save(MS,System.Drawing.Imaging.ImageFormat.Jpeg);

            //然后将其转换为JPEG流格式为JPEG字节数组格式
            byte []的BUF =新的字节[ms.Length]
            ms.Read(BUF,0,buf.Length);

            //改变Tiff格式的byte [] ImageGallery到JPEG的byte []
            imageGallery.ImageContent = BUF;
        }
    }
    返回imageGalleries;
}
 

  • 在另一个解决方案是使用 LibTiff.Net 库直接转换字节[] 的TIFF为 WritableBitmap 直接在Silverlight中。

不过,通过挖掘他们的示例应用程序,或使用反射看到源$ C ​​$ C函数后,我仍然无法弄清楚如何使用他们的图书馆为TIFF的字节转换为 WritableBitmap JPEG(或PNG),因为他们的样品只显示了使用搜索的文件目录的TIFF的API。就我而言,我没有在服务器上的现有文件。

有人可以帮助我如何显示在Silverlight中的图像控制的TIFF文件?

我搜索了论坛,但没有找到任何这坚实的答案。

感谢

解决方案
  1. 参考LibTiff.net

  2. 加入这个类:

     使用系统;
    使用System.Collections.Generic;
    使用System.IO;
    使用System.Windows.Media.Imaging;
    使用BitMiracle.LibTiff.Classic;
    
    命名空间CoreTechs.X9
    {
        公共静态类TiffUtility
        {
            公共静态的Tiff CreateTiff(此字节[]字节)
            {
                MemoryStream的毫秒=新的MemoryStream(字节);
                TIFF TIFF = Tiff.ClientOpen(内存,R,MS,新TiffStream());
                返回TIFF;
            }
    
            公共静态的IEnumerable&LT; WriteableBitmap的&GT; ConvertToWriteableBitmaps(此TIFF文件TIFF)
            {
                如果(TIFF == NULL)
                    抛出新ArgumentNullException(TIFF,TIFF为空);
    
                短迪尔斯= tiff.NumberOfDirectories();
    
                的for(int i = 0; I&LT;迪尔斯;我++)
                {
                    如果(tiff.SetDirectory((短)我))
                    {
                        INT tileCount = tiff.NumberOfTiles();
                        INT stripCount = tiff.NumberOfStrips();
    
                        VAR frameWidthField = tiff.GetField(TiffTag.IMAGEWIDTH);
                        VAR frameHeightField = tiff.GetField(TiffTag.IMAGELENGTH);
                        VAR COM pressionField = tiff.GetField(TiffTag.COM preSSION);
                        VAR xResolutionField = tiff.GetField(TiffTag.XRESOLUTION);
                        VAR yResolutionField = tiff.GetField(TiffTag.YRESOLUTION);
                        VAR samplesPerPixelField = tiff.GetField(TiffTag.SAMPLESPERPIXEL);
    
                        INT frameWidth = frameWidthField = NULL和放大器;!&安培; frameWidthField.Length&GT; 0? frameWidthField [0] .ToInt():0;
                        INT frameHeight = frameHeightField = NULL和放大器;!&安培; frameHeightField.Length&GT; 0? frameHeightField [0] .ToInt():0;
                        VAR COM pression = com的pressionField = NULL和放大器;!&安培; COM pressionField.Length&GT; 0? (比较pression)COM pressionField [0] .value的:COM pression.NONE;
                        VAR xResolution = xResolutionField = NULL和放大器;!&安培; xResolutionField.Length&GT; 0?新的双(xResolutionField [0] .ToDouble()):空;
                        VAR yResolution = yResolutionField = NULL和放大器;!&安培; yResolutionField.Length&GT; 0?新的双(yResolutionField [0] .ToDouble()):空;
                        VAR samplesPerPixel = samplesPerPixelField = NULL和放大器;!&安培; samplesPerPixelField.Length&GT; 0? samplesPerPixelField [0]的ToString():的String.Empty;
    
                        如果(xResolution = NULL和放大器;!&安培; yResolution == NULL)
                        {
                            yResolution = xResolution;
                        }
    
                        VAR缓冲区=新的INT [frameWidth * frameHeight]。
                        tiff.ReadRGBAImage(frameWidth,frameHeight,缓冲区);
    
                        VAR BMP =新的WriteableBitmap的(frameWidth,frameHeight);
                        对于(INT Y = 0; Y&LT; frameHeight; Y ++)
                        {
                            VAR ytif = Y * frameWidth;
                            VAR ybmp =(frameHeight  -  Y  -  1)* frameWidth;
    
                            为(中间体X = 0 X  - 其中; frameWidth; X ++)
                            {
                                VAR到currentValue =缓冲区[ytif + X]
    
                                //移的Tiff的RGBA格式到Silverlight WriteableBitmap的的ARGB格式
                                bmp.Pixels [ybmp + X] = Tiff.GetB(到currentValue)| Tiff.GetG(到currentValue)&LT;&LT; 8 | Tiff.GetR(到currentValue)&LT;&LT; 16 | Tiff.GetA(到currentValue)&LT;&LT; 24;
                            }
                        }
    
                        得到的回报BMP;
                    }
                }
            }
        }
    }
     

  3. 使用的exension方法是这样的:

     字节[] myHappyTiffData = GetMyTiffBytesFromSomewhere();
    WriteableBitmap的BMP = myHappyTiffData.CreateTiff()ConvertToWriteableBitmaps()FirstOrDefault()。
    myImageControl.Source = BMP;
     

I created a window service to put all of my TIFF files into database and stored them as Byte[].

Now I want to be able to display them through Silverlight Image control

So i use the Converter during binding XAML in order to convert the Byte[] to Bitmap because the Image.Source only accept eitheir URI (I don't have the file stored on server so can't use this method) or 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;

However, I get the exception at bmi.SetSource(ms) because Silverlight only supports JPEG and PNG images.

So I did more research and knew that i should convert the bytes of TIFF to bytes of JPEG or PNG then it will work.

To do that I tried two methods:

  • Doing the conversion on server: in my RIA service call, after retrieving the ImageGallery, I loop through the available image to convert the bytes of TIFF to the bytes of JPEG.

BUT IT DOESN'T WORK.... Can you tell me where I did wrong?

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;
}

  • The other solution is to use LibTiff.Net library to convert directly the Byte[] of TIFF to WritableBitmap directly on Silverlight.

However, after digging through their sample application or using Reflector to see the source code functions, I still can't figure out how to use their library to convert the bytes of TIFF to WritableBitmap JPEG (or PNG) because their sample only show the API for using the search the TIFF in a file directory. In my case, I don't have an existing file on server.

Can someone help me how to show the TIFF file on Image control of Silverlight?

I searched the forum but didn't find any solid answer for this.

thanks

解决方案

  1. Reference LibTiff.net

  2. Add this class:

    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. Use the exension methods like this:

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

这篇关于如何显示TIFF(以字节[]的形式)对Silverlight的图像控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆