WPF BitmapImage分为两部分

时间:2015-08-21 15:06:35

标签: c# wpf bitmap

我在WPF应用程序中弄乱了Bitmaps。我在后台线程上收到一个字节数组,转换器将其更改为bitmapSource进行绑定。

但是,如果我尝试在内存中直接创建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]

我检查了高度,宽度,pixelFormat,pixelPalette,dpi等都与我读入的文件匹配,但仍然显示不正确。甚至检查了文件的标题。

我已经尝试过使用PngBitmapEncoder的BitmapImages,BitmapSources,WriteableBitmaps,但我仍然保持不变。我觉得要么我错过了一些基本的东西,要么就是一个错误。我认为切片是错误的,但没有倾斜,

我在图片中显示它:

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

有什么想法吗?

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

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

所以我可以计算文件的像素偏移量,然后复制我需要的字节,但是我选择将数组包装在内存流中并使用BmpBitmapDecoder,因为它更简单

setActive:function(cmp) {
    cmp.myActiveListeners = cmp.eventStore.on({
        destroyable: true,
        load:cmp.refreshStores,
        filterchange:cmp.refreshStores,
        scope:cmp
    });
},
setInactive:function(cmp) {
    Ext.destroy(cmp.myActiveListeners);
},