2015-08-21 52 views
0

我正在搞乱WPF应用程序中的位图。我在后台线程上接收到一个字节数组,并且转换器将其更改为bitmapSource进行绑定。WPF BitmapImage切成两半

但是,如果我尝试直接在内存中创建bitmapSource并显示它,它会将图像拆分为两部分。我没有很多位图经验,但足以让我可以随时显示图像。

enter image description here

奇怪的是,如果我第一次写的文件出来,然后再在读它,它的工作原理。

File.WriteAllBytes(@"C:\woot2.bmp", bytes); 

var bmp = new BitmapImage(new Uri(@"C:\woot2.bmp")); 
var height = bmp.Height;      // 480.0 
var width = bmp.Width;       // 640.0 
var format = bmp.Format;      // Indexed8 
var dpix = bmp.DpiX;       // 96.0 
var dpiY = bmp.DpiY;       // 96.0 
var pallete = bmp.Palette;      // Gray256 
var cacheOption = bmp.CacheOption;    // Default 
var createOptions = bmp.CreateOptions;   // None 
return bmp; 

[Correct Image[1]

我检查高度,宽度,像素格式,pixelPalette,DPI等所有我读的文件相匹配,它仍然显示其不正确。甚至检查了文件的标题。

我试过BitmapImages,BitmapSources,WriteableBitmaps与PngBitmapEncoder,我仍然得到相同的。我觉得我要么缺少一些基本的东西,要么有一个缺陷。我以为切片是错误的,但有没有歪斜,

我是一个图像中显示它:

<Image Width="640" Height="480" 
    Source="{Binding VisionImage, Mode=OneWay,UpdateSourceTrigger=PropertyChanged, 
    Converter={StaticResource VisionImageConverter} }"></Image> 

下面的代码我得把它转换目前

var width = 640; 
var height = 480; 
var dpiX = 96; 
var dpiY = 96; 
var pixelFormat = PixelFormats.Indexed8; 
var palleteFormat = BitmapPalettes.Gray256; 
var stride = 4* (((width*pixelFormat.BitsPerPixel) + 31)/32); 
return BitmapSource.Create(width, height, dpiX, dpiY, 
         pixelFormat, palleteFormat, bytes, stride); 

有任何想法吗?

+0

如果问题是关于传递给File.WriteAllBytes(@“C:\ woot2.bmp”,bytes)的'bytes';',你有一个编码的BMP缓冲区,而不是一个原始像素缓冲区。您不应该使用它调用BitmapSource.Create。相反,从字节数组中创建一个MemoryStream并将其分配给BitmapImage的'StreamSource'属性。 – Clemens

+0

我试过一个位图图像(当然这是什么新的BitmapImage(新的Uri(“....”))正在使用,只是原始字节? –

+0

顺便说一句你的步幅公式是错误的,应该是'bytesPerPixel = (bitsPerPixel + 7)/ 8'然后'stride = width * bytesPerPixel'。 – Aybe

回答

0

好了,所以这个答案最终被非常简单。我只给它整个位图文件数组,而不是只给它像素数组。我认为当你从一个文件创建一个bitmapImage时,它必须在内部使用一个bitmapDecoder。这就是为什么写入文件然后再读取它的原因。

所以我可以计算的像素从文件偏移量,然后复制,我需要的字节数,但我选择了包裹在一个MemoryStream的数组,并使用BmpBitmapDecoder,因为它是简单

using(var ms = new MemoryStream(bytes)) 
{ 
    var decoder = new BmpBitmapDecoder(ms, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnDemand); 
    return new WriteableBitmap(decoder.Frames.FirstOrDefault()); 
} 
1

显然,字节数组不包含原始像素数据,但是是一个编码的BMP缓冲区,因此您无法通过BitmapSource.Create创建BitmapSource。

而应该创建一个从编码BMP缓冲区的BitmapImage这样的:

var bitmapImage = new BitmapImage(); 
using (var stream = new MemoryStream(bytes)) 
{ 
    bitmapImage.BeginInit(); 
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad; 
    bitmapImage.StreamSource = stream; 
    bitmapImage.EndInit(); 
} 

或可替换地创建这样一个BitmapFrame:

BitmapFrame bitmapFrame; 
using (var stream = new MemoryStream(bytes)) 
{ 
    bitmapFrame = BitmapFrame.Create(stream, 
     BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 
} 
+0

我试过这个确切的代码,并得到完全相同的结果:(我会尝试位图框架选项,虽然感谢 –

+0

我想我只是不明白我怎么可以写出文件,它看起来很完美,但是当我使用完全相同的字节直接在我的代码中创建它,它拧了起来 –