Question

Avant, quand j'utilisais win32, j'ai utilisé FreeImage pour charger et enregistrer des bitmaps de bits profondeur supérieure à 8 bits. C'est chaque image que je travaille, depuis que je fais l'imagerie médicale, et avant tout le monde dit quoi que ce soit, oui, moi et mes clients ont dépensé beaucoup d'argent sur haute luminosité, moniteurs de contraste élevé avec 11 ou 12 bits de plage dynamique . En fait, si vous êtes curieux, par l'ACR pour l'exécution de la mammographie incldue une surveiller au moins 10 bits de la plage dynamique.

Je viens passé à x64 pour les frais généraux de mémoire et d'obtenir tout mon développement sur une plate-forme et le mode compilation. Je préfère ne pas revenir à win32, et mes clients sont là avec moi (et forçant vraiment le changement). FreeImage ne compile pas sur 64 fenêtres de bit; il a une directive _asm dans le code que le compilateur ne peut pas gérer.

Je pensais que je vais essayer le support natif .NET dans les classes Microsoft. Longue histoire courte: ils ne travaillent pas, et échouent avec les messages d'erreur très limité. Je pense qu'il est parce que Microsoft ne supporte toujours pas la classe Format16bppGrayScale.

Peut-être qu'il ya un problème dans mon code. Voici mon code pour l'écriture:

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();

Ce code provoque le plantage du programme avec

An unhandled exception of type 
 'System.Runtime.InteropServices.ExternalException' occurred in 
 System.Drawing.dll

Additional information: A generic error occurred in GDI+.

Intéressant, surtout que je ne veux plus jamais dessiner cette image à l'écran comme celui-ci (même si ce serait bien!), Mais je veux juste utiliser la sauvegarde / fonctionnalité de charge. L'image ne s'écrit sur le disque (même si le programme se bloque), et le code de lecture suivante bloque également le programme:

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

Ce code provoque le plantage du programme avec l'erreur:

An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll

Additional information: Parameter is not valid.

Ces résultats me disent que Microsoft n'a pas encore fixé la partie Format16bppGrayScale de l'énumération PixelFormat. C'est dommage.

Alors, que puis-je utiliser pour charger et enregistrer 16 bits des images en niveaux de gris sur 64 bits avec .NET?

(EDIT:. Je dois ajouter que si je peux sauver les images DICOM, je dois faire des expériences sur des données non-patient pour vérifier que les algorithmes sont solides, et ainsi de suite DICOM nécessite un ensemble de UIDs et d'autres champs obligatoires qui sont trop pour ce que je dois, je juste besoin d'images, et non les données du patient, au moment)

.
Était-ce utile?

La solution

FreeImage peut être compilé à 64 bits. En suivant les instructions ici peut contourner la directive _asm. Il y a aussi une dll 64 bits compilé au bas de la page.

La dernière version (3.15.1) contient déjà ce correctif. J'ai pris la distribution source pour essayer (je suis curieux de l'utiliser FreeImage dans mon propre projet) et la plate-forme x64 compile bien tout de suite.

Autres conseils

Je ne suis pas vraiment répondre à votre question, mais ont déjà utilisé le composant ImageDraw vendu par Neodnyamic et nous reviendrions certainement recommander (et utiliser) à nouveau. Il est gratuit, mais vaut bien un petit investissement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top