简体   繁体   English

WPF BitmapImage分为两部分

[英]WPF BitmapImage sliced in two

I'm messing about with Bitmaps in a WPF application. 我在WPF应用程序中弄乱了位图。 I receive the a byte array on a background thread and a converter changes it to a bitmapSource for binding. 我在后台线程上收到一个字节数组,转换器将其更改为bitmapSource进行绑定。

However, if I try to directly create the bitmapSource in memory and display it, it splits the image into two. 但是,如果我尝试直接在内存中创建bitmapSource并显示它,它将图像分成两部分。 I'm haven't had a great deal of experience with bitmaps but enough so that I could always display images. 我对位图没有太多的经验,但是足够使我始终可以显示图像。

在此处输入图片说明

The weird thing, is that if I write the file out first, then read it back in, it works. 奇怪的是,如果我先将文件写出,然后再读回,那么它将起作用。

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;

[ [ 正确的图像[1]

I've checked the height, width, pixelFormat, pixelPalette, dpi etc all match the file that I read in and it still displays it incorrectly. 我检查了高度,宽度,pixelFormat,pixelPalette,dpi等是否都与我读入的文件匹配,但仍无法正确显示。 Even checked the header of the file. 甚至检查了文件头。

I've tried BitmapImages, BitmapSources, WriteableBitmaps with PngBitmapEncoder and I still get the same. 我已经尝试了PngBitmapEncoder的BitmapImages,BitmapSources,WriteableBitmaps,但我仍然得到了相同的结果。 I feel like either i'm missing something fundamental or there's a bug. 我觉得我要么缺少基本的东西,要么有错误。 I thought the slice was wrong, but there's no skewing, 我以为切片错了,但是没有歪斜,

i'm displaying it in an image: 我在图像中显示它:

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

Here's the code i've got to convert it currently 这是我目前要转换的代码

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

Any ideas? 有任何想法吗?

Apparently the byte array does not contain raw pixel data, but an encoded BMP buffer, so you can't create a BitmapSource by BitmapSource.Create . 显然,字节数组不包含原始像素数据,而是一个经过编码的BMP缓冲区,因此您不能通过BitmapSource.Create创建一个BitmapSource.Create

You should instead create a BitmapImage from the encoded BMP buffer like this: 您应该改为从编码的BMP缓冲区创建BitmapImage,如下所示:

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

Or alternatively create a BitmapFrame like this: 或者创建一个BitmapFrame像这样:

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

Okay, so the answer for this ended up being quite simple. 好的,因此答案很简单。 Instead of giving it just the pixel array, I was giving it the whole bitmap file array. 我没有给它仅像素数组,而是给了它整个位图文件数组。 I think when you create a bitmapImage from a file it must use a bitmapDecoder internally. 我认为从文件创建bitmapImage时,必须在内部使用bitmapDecoder。 Which is why writing to a file and then reading it back worked. 这就是为什么写入文件然后将其读回的原因。

So I could have calculated the pixel offset from the file and then copied the bytes that I needed, but I chose to wrap the array in a memorystream and use a BmpBitmapDecoder because it was simpler 因此我可以计算出文件中的像素偏移量,然后复制所需的字节,但是我选择将数组包装在内存流中并使用BmpBitmapDecoder,因为它更简单

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM