之前,當我使用win32時,爲了加載和保存位深度大於8位的位圖,我使用了FreeImage。這是我工作的每一張圖片,因爲我正在做醫學成像,在任何人說什麼之前,是的,我和我的客戶花費了大量金錢在高亮度,高對比度的顯示器上,顯示器的動態範圍爲11或12位。事實上,如果你很好奇,requirements by the ACR for running mammography包含一個至少有10位動態範圍的顯示器。如何在.net x64中保存/加載16位圖像?
我剛剛切換到x64的內存開銷,並將我所有的開發都集成到一個平臺和編譯模式中。我寧願不回到win32,我的客戶就在我身邊(並且真正強迫變化)。 FreeImage不能在64位窗口上編譯;它在代碼中有一個_asm指令,編譯器無法處理。
我想我會嘗試Microsoft類中的本地.NET支持。長話短說:他們不工作,失敗的錯誤信息非常有限。我懷疑這是因爲微軟仍然不支持Format16bppGrayScale類。
也許我的代碼有問題。這是我寫的代碼:
Bitmap theBitmap = new Bitmap(inImage.XSize, inImage.YSize, PixelFormat.Format16bppGrayScale);
//have to go with lockbits
Rectangle rect = new Rectangle(0, 0, theBitmap.Width, theBitmap.Height);
System.Drawing.Imaging.BitmapData bmpData =
theBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
PixelFormat.Format16bppGrayScale);
IntPtr ptr = bmpData.Scan0;
int theByteSize = theBitmap.Width * theBitmap.Height *2;
byte[] theByteBuffer = new byte[theByteSize];
System.Buffer.BlockCopy(inImage.Data, 0, theByteBuffer, 0, theByteSize);
System.Runtime.InteropServices.Marshal.Copy(theByteBuffer, 0, ptr, theByteSize);
theBitmap.UnlockBits(bmpData);
theBitmap.Save(inDirectory + "\\" + inName);
theBitmap.Dispose();
此代碼導致程序崩潰與
An unhandled exception of type
'System.Runtime.InteropServices.ExternalException' occurred in
System.Drawing.dll
Additional information: A generic error occurred in GDI+.
有趣的,尤其是因爲我從來沒有想這個圖像繪製到這樣的畫面(雖然這將是很好!) ,但只想使用保存/加載功能。圖像不會被寫入磁盤(即使程序崩潰),和下面的閱讀代碼也導致程序崩潰:
Bitmap theBitmap = new Bitmap(theCompleteName, false);
ushort[] theData = new ushort[theBitmap.Width * theBitmap.Height];
int x, y;
switch (theBitmap.PixelFormat)
{
case PixelFormat.Format16bppGrayScale:
//have to go with lockbits
{
Rectangle rect = new Rectangle(0, 0, theBitmap.Width, theBitmap.Height);
System.Drawing.Imaging.BitmapData bmpData =
theBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
PixelFormat.Format16bppGrayScale);
IntPtr ptr = bmpData.Scan0;//scanline approach left over from FreeImage
for (y = 0; y < theBitmap.Height; ++y){
byte[] scanline = new byte[theBitmap.Width*2];
System.Runtime.InteropServices.Marshal.Copy(ptr, scanline, y * theBitmap.Width * 2, theBitmap.Width * 2);
System.Buffer.BlockCopy(scanline, 0, theData, y * theBitmap.Width * 2, theBitmap.Width * 2);
}
theBitmap.UnlockBits(bmpData);
}
break;
//for colors, just take the red and call it a day
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppArgb://really stupid reading code, always works
for (y = 0; y < theBitmap.Height; ++y) {
for (x = 0; x < theBitmap.Width; ++x) {
theData[y * theBitmap.Width + x] = (byte)(theBitmap.GetPixel(x, y).R);
}
}
break;
}
theNewImage = new ImageContainer(theData, theBitmap.Width, theBitmap.Height, inName, inAssessmentID);
theBitmap.Dispose();//not needed, anymore
此代碼導致程序崩潰與錯誤:
An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Parameter is not valid.
這些結果告訴我,微軟仍然沒有修復PixelFormat枚舉的Format16bppGrayScale部分。這太遺憾了。
那麼,我可以使用什麼來加載和保存x64與.NET的16位灰度圖像? (編輯:我應該補充說,雖然我可以省去DICOM圖像,但我需要在非患者數據上運行實驗來驗證算法是否正確,等等.DICOM需要一組UID和其他必需的這些字段對我所需要的是過度的;我現在只需要圖像,而不是耐心的數據)。
你是對的 - 截至目前,freeimage項目爲x64編譯。感謝您指出! – mmr