Frage

Früher, als ich wurde mit win32, habe ich Freeimage , um zum Laden und Speichern von Bitmaps von Bit Tiefe von mehr als 8 Bit. Das ist jedes Bild, das ich die Arbeit mit, da ich die medizinische Bildgebung mache, und bevor jemand etwas sagt, ja, ich und meine Kunden haben eine Menge Geld auf hohe Helligkeit, hohe Kontrast-Monitore mit 11 oder 12 Bit Dynamikbereich ausgegeben . In der Tat, wenn Sie neugierig sind, Anforderungen durch das ACR für laufende Mammographie incldue ein Monitor mit mindestens 10 Bits des dynamischen Bereichs.

Ich wechselte nur auf x64 für die Speichergemeinkosten und alle meine Entwicklung auf einer Plattform und Kompilieren-Modus zu gelangen. Ich möchte lieber nicht zu win32 zurück, und meine Kunden sind genau dort mit mir (und wirklich die Änderung zwingen). Freeimage lässt sich nicht kompilieren auf 64-Bit-Fenster; es hat eine _asm Richtlinie in dem Code, dass der Compiler kann einfach nicht damit umgehen.

Ich dachte, ich würde versuchen, die native .NET-Unterstützung in den Microsoft-Klassen. Lange Rede kurzer Sinn: Sie haben keine Arbeit, und nicht mit sehr begrenzten Fehlermeldungen. Ich vermute, es ist, weil Microsoft immer noch nicht die Format16bppGrayScale Klasse unterstützen.

Vielleicht ist 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, zumal ich noch nie so dieses Bild auf den Bildschirm zeichnen will (obwohl es schön wäre!), Will aber nur die Funktionalität Speicher / Laden verwenden. Das Bild bekommt auf der Platte geschrieben (obwohl das Programm stürzt ab), und der folgende Lese Code 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.

sagen Diese Ergebnisse mir, dass Microsoft immer noch nicht den Format16bppGrayScale Teil der Pixelformat-Enumeration festgelegt hat. Das ist eine Schande.

Was kann ich also zu Last verwenden und speichern 16-Bit-Graustufen-Bilder auf x64 mit .NET?

(EDIT:. Ich soll hinzufügen, dass, während ich DICOM-Bilder speichern Sie kann, ich brauche Versuche an Nicht-Patientendaten laufen zu lassen, um sicherzustellen, dass die Algorithmen sind Ton und so weiter DICOM erfordert eine Reihe von UIDs und anderen erforderlichen Feldern die sind übertrieben für das, was ich brauche;. ich habe gerade brauchen Bilder, und nicht die Patientendaten, zur Zeit)

War es hilfreich?

Lösung

Freeimage können zu x64 kompiliert werden. Nach den Anweisungen hier kann die _asm Richtlinie zu umgehen. Es gibt auch eine kompilierte 64-Bit-DLL am unteren Rand der Seite.

Die neueste Version (3.15.1) enthält bereits dieses Update. Ich habe die Source-Distribution aufgenommen, um zu versuchen (Ich bin neugierig Freeimage in meinem eigenen Projekt zu verwenden) und die x64-Plattform kompiliert feine sofort.

Andere Tipps

Ich antworte nicht wirklich Ihre Frage, aber vorher die ImageDraw Komponente von Neodnyamic und würde auf jeden Fall empfehlen (und benutzen) wieder. Es ist nicht kostenlos, aber es lohnt eine kleine Investition.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top