2015-08-21 87 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

我想我只是不明白我怎麼可以寫出文件,它看起來很完美,但是當我使用完全相同的字節直接在我的代碼中創建它,它擰了起來 –