Pregunta

Antes, cuando yo estaba usando Win32, solía FreeImage con el fin de cargar y guardar los mapas de bits de bits profundidad mayor que 8 bits. Eso es cada imagen que trabajo, ya que estoy haciendo imágenes médicas, y antes de que nadie dice nada, sí, yo y mis clientes han invertido mucho dinero en alto brillo, monitores de alto contraste con 11 o 12 bits de rango dinámico . De hecho, si usted es curioso, de la ACR para el funcionamiento de la mamografía incldue una supervisar con al menos 10 bits de gama dinámica.

Acabo de cambiar a x64 para los gastos generales de memoria y para obtener toda mi desarrollo en una sola plataforma y el modo de compilación. Yo prefiero no hacia atrás para Win32, y mis clientes están ahí conmigo (y realmente forzar el cambio). FreeImage no compila en 64 bits de Windows; que tiene una directiva _asm en el código que el compilador no puede manejar.

pensé que me gustaría probar el soporte de .NET nativo en las clases de Microsoft. En resúmen: no trabajan y fallan con mensajes de error muy limitadas. Sospecho que es porque Microsoft todavía no soporta la clase Format16bppGrayScale.

Tal vez hay un problema en mi código. Aquí está mi código para escribir:

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

Este código se bloquea el programa con

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

Additional information: A generic error occurred in GDI+.

interesante, sobre todo porque no quiero volver a dibujar esta imagen a la pantalla de este tipo (aunque sería agradable!), Sino que sólo quiere usar la funcionalidad de guardar / cargar. La imagen no se escriben en el disco (a pesar de que el programa se bloquea), y el siguiente código de lectura también bloquea el programa:

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

Este código se bloquea el programa con el error:

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

Additional information: Parameter is not valid.

Estos resultados me dicen que Microsoft todavía no ha fijado la parte Format16bppGrayScale de la enumeración PixelFormat. Eso es una vergüenza.

Entonces, ¿qué puedo utilizar para cargar y guardar 16 bits en escala de grises de 64 bits con .NET?

(EDIT:. Debo añadir que, si bien puedo salvar a cabo las imágenes DICOM, necesito llevar a cabo experimentos sobre datos que no son de pacientes para verificar que los algoritmos son sólidos, y así sucesivamente DICOM requiere un conjunto de UID y otros campos requeridos que son excesivos para lo que necesito, yo sólo necesito imágenes y no los datos del paciente, en el momento)

.
¿Fue útil?

Solución

FreeImage puede compilarse a x64. Siguiendo las instrucciones aquí puede moverse por la Directiva _asm. También es un compilado DLL de 64 bits en la parte inferior de la página.

La última versión (3.15.1) ya contiene esta revisión. He recogido la distribución fuente de probar (estoy siendo curiosa utilizar FreeImage en mi propio proyecto) y la plataforma x64 compila bien de inmediato.

Otros consejos

No estoy respondiendo a tu pregunta, pero he utilizado previamente el componente ImageDraw vendido por Neodnyamic y sin duda recomendaría (y usar) de nuevo. No es gratis, pero bien vale la pena una pequeña inversión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top