我在WPF应用程序中弄乱了Bitmaps。我在后台线程上收到一个字节数组,转换器将其更改为bitmapSource进行绑定。
但是,如果我尝试在内存中直接创建bitmapSource并显示它,它会将图像分成两部分。我没有很多使用位图的经验,但足以让我总能显示图像。
奇怪的是,如果我先将文件写出来,然后再读回来,那就可以了。
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;
[
我检查了高度,宽度,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);
有什么想法吗?
答案 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);
},