Question

J'ai une application qui permet à un utilisateur de définir une région d'une image et enregistrer cette région dans le fichier. J'ai couru contre un accroc que je ne peux pas régler. Le Bitmap que je crée pour peindre la région sélectionnée sur est coincé avec un ImageFormat de « MemoryBmp », il semble que ce soit le ImageFormat qui est défini pour tout bitmaps chargé non fichier. Le problème est mon Bitmap est créé en mémoire et je veux enregistrer en tant que CCITT4 TIFF mais je bitonal suis obtenir un « Une erreur générique est produite dans GDI + » Exception. Je suis assez confiant cela est dû au fait que la propriété Image.RawFormat est que MemoryBmp redoutée.

Image.Save () a une surcharge qui prend un paramètre ImageFormat et quand j'utilise ce passage ImageFormat.Tiff il sauve bien, mais je ne suis pas l'occasion de préciser mes paramètres du codeur.

La solution possible que je peux penser est d'enregistrer sur le disque à l'aide Image.Save (image, ImageFormat) puis le recharger (RawFormat va maintenant être correctement réglé sur ImageFormat.Tif) et enregistrer à nouveau les THEN passant paramètres de l'encodeur. C'est juste si stupide, il doit y avoir une meilleure façon.

Voici une ciselée code (ce qui est juste des trucs à l'essai) qui devrait vous donner une idée de ce que je fais dans le cas où ma description plus tôt n'a pas été assez claire:

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, je dois mentionner que « loadedIimage » est en effet une image tiff, je suis passé la référence à loadedImage au Bitmap.ctor () pour voir si cela la moindre idée dans ce qu'il a affaire, mais il n'a fait aucune différence.

Était-ce utile?

La solution

Figured que CCITT4 ne nécessite images à deux tons, ha! Alors je suis parti googler et suis tombé sur un article CodeProject et snooped autour de la source. L'auteur a fourni une méthode assez décent pour convertir 32bppARGB à 1bpp bi-tons. Je l'ai essayé et il est rapide (test montrent environ 34 ms pour une seule page) et il a fait l'affaire!

Je réponds à ma propre question. J'espère que cela au moins aide quelqu'un d'autre qui vient à travers ce problème.

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