Bevor ich Win32 verwendet habe, habe ich FreeImage verwendet, um Bitmaps mit einer Bittiefe von mehr als 8 Bit zu laden und zu speichern. Das ist jedes Bild, mit dem ich arbeite, seit ich medizinische Bildgebung betreibe, und bevor irgendjemand etwas sagt, ja, ich und meine Kunden haben viel Geld für kontrastreiche Monitore mit hoher Helligkeit und 11 oder 12 Bit Dynamik ausgegeben . In der Tat, wenn Sie neugierig sind, requirements by the ACR for running mammography in einem Monitor mit mindestens 10 Bit Dynamikbereich.Wie kann ich ein 16-Bit-Bild in .net x64 speichern/laden?
Ich habe gerade auf x64 für die Speicher-Overheads und um alle meine Entwicklung auf eine Plattform und Compiling-Modus zu bekommen. Ich möchte lieber nicht zu win32 zurückkehren, und meine Kunden sind direkt bei mir (und erzwingen wirklich den Wechsel). FreeImage kompiliert nicht in 64-Bit-Fenstern; Es hat eine _asm-Direktive im Code, die der Compiler nicht verarbeiten kann.
Ich dachte, ich würde versuchen, die native .NET-Unterstützung in den Microsoft-Klassen. Lange Rede, kurzer Sinn: Sie funktionieren nicht und scheitern mit sehr eingeschränkten Fehlermeldungen. Ich vermute, dass Microsoft die Format16bppGrayScale-Klasse immer noch nicht unterstützt.
Vielleicht gibt es ein Problem in meinem Code. Hier ist mein Code für das Schreiben:
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();
Dieser Code stürzt das Programm mit
An unhandled exception of type
'System.Runtime.InteropServices.ExternalException' occurred in
System.Drawing.dll
Additional information: A generic error occurred in GDI+.
interessant, vor allem, da ich nie dieses Bild auf dem Bildschirm wie folgt zeichnen möchten (auch wenn es schön wäre!) , möchte aber nur die Funktion zum Speichern/Laden verwenden. Das Bild bekommt auf der Platte geschrieben (obwohl das Programm stürzt ab), und der folgende Lesecode stürzt das Programm auch:
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
Dieser Code stürzt das Programm mit dem Fehler:
An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Parameter is not valid.
Diese Ergebnisse sagen Sie mir, dass Microsoft den Format16bppGrayScale-Teil der PixelFormat-Enumeration noch nicht behoben hat. Das ist eine Schande.
Was kann ich verwenden, um 16-Bit-Graustufenbilder auf x64 mit .NET zu laden und zu speichern?
(EDIT:. Ich sollte hinzufügen, dass, während ich DICOM-Bilder speichern Sie können, ich Versuche an Nicht-Patientendaten ausgeführt werden müssen, um sicherzustellen, dass die Algorithmen sind Ton und so weiter DICOM eine Reihe von UIDs und andere erfordert erforderlichen Felder, die für das, was ich brauche, übertrieben sind, ich brauche im Moment nur Bilder und keine Patientendaten.
Sie haben Recht - ab sofort kompiliert das freeimage-Projekt für x64. Danke für das Aufzeigen! – mmr