Pregunta

Tengo una aplicación que permite a un usuario definir una región de una imagen y guardar esa región a archivo. Me he topado con un obstáculo que no pueda resolver. El mapa de bits que se crea para pintar la región seleccionada se ha quedado atascado en con un ImageFormat de "MemoryBmp", parece ser que este es el ImageFormat que se establece para cualquiera que no sea el archivo cargado mapas de bits. El problema es mi mapa de bits se crea en la memoria y quiero guardarlo como un archivo TIFF bitonal CCITT4 pero yo estoy poniendo "se produjo un error genérico en GDI +" una excepción. Estoy bastante seguro de que esto es debido al hecho de la propiedad Image.RawFormat se temía que MemoryBmp.

Image.Save () tiene una sobrecarga que toma un parámetro ImageFormat y cuando uso que pasa ImageFormat.Tiff se ahorra bien, pero no tienen la oportunidad de especificar mis parámetros del codificador.

La única solución posible que se me ocurre es guardar en el disco utilizando Image.Save (Imagen, ImageFormat) vuelva a cargarlo (RawFormat será ahora correctamente puede configurar para ImageFormat.Tif) y luego guardar pasando de nuevo la configuración del codificador. Eso es una estupidez sin embargo, tiene que haber una mejor manera.

A continuación, se cortó una de código (esto es sólo probando cosas) que debe darle una idea de lo que estoy haciendo en el caso de mi descripción anterior no era lo suficientemente claro:

SizeF dpiScale = GetScreenToImageDPIRatio(loadedImage);
using (Bitmap image = new Bitmap(loadedImage,
    (int)(_cropBox.Width * dpiScale.Width),
    (int)(_cropBox.Height * dpiScale.Height)))
{
    image.SetResolution(loadedImage.HorizontalResolution, 
        loadedImage.VerticalResolution);

    using (Graphics g = Graphics.FromImage(image))
    {
        g.DrawImage(loadedImage, 0, 0, new Rectangle(
            (int)(_cropBox.Location.X * dpiScale.Width),
            (int)(_cropBox.Location.Y * dpiScale.Height),
            (int)(_cropBox.Width * dpiScale.Width),
            (int)(_cropBox.Height * dpiScale.Height)),
            GraphicsUnit.Pixel);
    }

    //  It's stuck as a MemoryBmp so none of these checks will work
    if (true || image.RawFormat.Equals(ImageFormat.Tiff))
    {
        ImageCodecInfo tiffCodecInfo = ImageUtils.GetEncoderInfo("image/tiff");
        EncoderParameters myEncoderParameters = new EncoderParameters(2);

        myEncoderParameters.Param[0] = new
            EncoderParameter(System.Drawing.Imaging.Encoder.Compression,
                (long)EncoderValue.CompressionCCITT4);
        myEncoderParameters.Param[1] = new
            EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 1L);

        image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
            tiffCodecInfo, myEncoderParameters);

        //  The file is a "MemoryBmp" and it's screwing things up
        //image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
        //    ImageFormat.Tiff);
    }
    else
    {
        //  other format saving support, blah blah blah
    }
}

Oh, debo mencionar que "loadedIimage" una imagen TIFF es, en efecto, pasé la referencia a loadedImage a la Bitmap.ctor () para ver si eso ni idea en lo que se está tratando con, pero no había ninguna diferencia.

¿Fue útil?

Solución

dimos cuenta de que sí requiere CCITT4 imágenes bitonales, ja! Así que me fui buscando en Google y me encontré con un CodeProject artículo y snooped alrededor de la fuente. El autor proporciona un método bastante decente para convertir 32bppARGB a 1bpp de dos tonos. Lo probé y es rápido (mostrar prueba de alrededor de 34 ms para una sola página) y lo hizo el truco!

Estoy respondiendo a mi propia pregunta. Espero que esto ayuda a al menos otra persona que se encuentra con este problema.

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