2013-03-07 95 views
12

我有一个代表图像原始数据的byte[]。我想将其转换为BitmapImage如何将字节[]转换为BitmapImage?

我试了几个例子,我发现,但我一直得到以下异常

“适合来完成这个操作没有成像部件被发现。”

我认为这是因为我的byte[]实际上并不代表一个图像,而只是原始位。 所以我的问题是如上所述是如何将原始位的字节[]转换为BitmapImage

回答

8

当你的字节数组包含一个位图的原始像素数据,您可以创建一个BitmapSource(这是基类的BitmapImage)的静态方法BitmapSource.Create

但是,您需要指定位图的几个参数。您必须事先知道缓冲区的宽度和高度以及PixelFormat

byte[] buffer = ...; 

var width = 100; // for example 
var height = 100; // for example 
var dpiX = 96d; 
var dpiY = 96d; 
var pixelFormat = PixelFormats.Pbgra32; // for example 
var bytesPerPixel = (pixelFormat.BitsPerPixel + 7)/8; 
var stride = bytesPerPixel * width; 

var bitmap = BitmapSource.Create(width, height, dpiX, dpiY, 
           pixelFormat, null, buffer, stride); 
+0

在Windows Phone 8上,以上不起作用,因为BitmapSource不支持创建选项。你会知道任何替代品吗? – vishal 2013-07-18 04:09:29

+1

@vishal你将不得不使用[WriteableBitmap](http://msdn.microsoft。COM/EN-US /库/窗/应用/ windows.ui.xaml.media.imaging.writeablebitmap.aspx)。 – Clemens 2013-07-18 05:30:03

+0

谢谢。我已经在尝试这个选项了:http://stackoverflow.com/questions/17714662/convert-int-to-byte-type-pointer-in-c-sharp/17715106?noredirect=1#17715106 – vishal 2013-07-18 05:31:04

-1

从原始字节创建一个MemoryStream并将其传递到您的位图构造函数中。

像这样:

MemoryStream stream = new  MemoryStream(bytes); 
Bitmap image = new Bitmap(stream); 
+0

你指的是'System.Drawing.Bitmap',它不是WPF。 – Clemens 2013-03-07 13:17:03

11
public static BitmapImage LoadFromBytes(byte[] bytes) 
{ 
    using (var stream = new MemoryStream(bytes)) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
     var image = new BitmapImage(); 
     image.BeginInit(); 
     image.StreamSource = stream; 
     image.EndInit(); 

     return image; 
    } 
} 
+0

其实,我试过这个,但是直到我在这个问题上添加了来自OP的代码行后才起作用:http://stackoverflow.com/questions/35831893/bitmapimage-to-byte-and-reverse:'image。 CreateOptions = BitmapCreateOptions.PreservePixelFormat; image.CacheOption = BitmapCacheOption.OnLoad;' - 否则我只是有一个空白的图像区域。 – vapcguy 2016-10-12 00:54:04

0

我跑过这个相同的错误,但这是因为我的数组没有得到充实的实际数据。我有一个字节数组,它等于它应该是的长度,但值仍然是0 - 他们还没有被写入!

我的特别问题 - 我怀疑其他人也会遇到这个问题 - 这是因为OracleBlob参数。我不认为我需要它,并认为我可以做这样的事情:

DataSet ds = new DataSet(); 
OracleCommand cmd = new OracleCommand(strQuery, conn); 
OracleDataAdapter oraAdpt = new OracleDataAdapter(cmd); 
oraAdpt.Fill(ds) 

if (ds.Tables[0].Rows.Count > 0) 
{ 
    byte[] myArray = (bytes)ds.Tables[0]["MY_BLOB_COLUMN"]; 
} 

我是多么的错!要真正获得该blob中的实际字节,我需要将该结果实际读入OracleBlob对象。相反,填充数据集/ DataTable的,我这样做:

OracleBlob oBlob = null; 
byte[] myArray = null; 
OracleCommand cmd = new OracleCommand(strQuery, conn); 
OracleDataReader result = cmd.ExecuteReader(); 
result.Read(); 

if (result.HasRows) 
{ 
    oBlob = result.GetOracleBlob(0); 
    myArray = new byte[oBlob.Length]; 
    oBlob.Read(array, 0, Convert.ToInt32(myArray.Length)); 
    oBlob.Erase(); 
    oBlob.Close(); 
    oBlob.Dispose(); 
} 

然后,我可以采取myArray和做到这一点:

if (myArray != null) 
{ 
    if (myArray.Length > 0) 
    { 
     MyImage.Source = LoadBitmapFromBytes(myArray); 
    } 
} 

而且我从对方的回答修订LoadBitmapFromBytes功能:

public static BitmapImage LoadBitmapFromBytes(byte[] bytes) 
{ 
    var image = new BitmapImage(); 
    using (var stream = new MemoryStream(bytes)) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
     image.BeginInit(); 
     image.StreamSource = stream; 
     image.CreateOptions = BitmapCreateOptions.PreservePixelFormat; 
     image.CacheOption = BitmapCacheOption.OnLoad; 
     image.UriSource = null; 
     image.EndInit(); 
    } 

    return image; 
}