Domanda

Ho un'applicazione che consente all'utente di definire una regione di un'immagine e salvare quella regione al file. Ho eseguito contro un intoppo che non riesco a risolvere. Il Bitmap che creo per dipingere la regione selezionata su è bloccato con un FormatoImmagine di "MemoryBmp", sembra che questo è il FormatoImmagine che è impostato per qualsiasi diverso da un file caricato bitmap. Il problema è il mio bitmap viene creata in memoria e voglio salvarlo come CCITT4 TIFF bitonale ma sto ricevendo "Si è verificato un errore generico in GDI +" un'eccezione. Sono abbastanza fiducioso questo è dovuto al fatto che la proprietà Image.RawFormat è che temuto MemoryBmp.

Image.Save () ha un overload che accetta un parametro FormatoImmagine e quando uso che passa ImageFormat.Tiff si salva bene, ma io non avere l'opportunità di specificare i miei parametri dell'encoder.

L'eventuale unica soluzione mi viene in mente è quello di salvare su disco utilizzando Image.Save (Immagine, FormatoImmagine) poi ricaricarla (Rawformat sarà ora correttamente essere impostato su ImageFormat.Tif) e quindi salvare di nuovo passando le impostazioni dell'encoder. Questo è solo stupido, però, ci deve essere un modo migliore.

Qui è un snipped di codice (questo è solo testando roba) che dovrebbe dare un'idea di quello che sto facendo nel caso in cui la mia descrizione precedente non era abbastanza chiaro:

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, vorrei ricordare che "loadedIimage" è davvero un'immagine TIFF, ho passato il riferimento alla loadedImage al Bitmap.ctor () per vedere se questo sarebbe indizio in per quello che è, ma si tratta di non faceva alcuna differenza.

È stato utile?

Soluzione

capito che CCITT4 richiede immagini bitonali, ah! Così sono andato fuori googling e sono imbattuto in un CodeProject articolo e snooped in giro la fonte. L'autore ha fornito un metodo di decente abbastanza per convertire 32bppARGB a 1bpp bitonale. Ho provato ed è veloce (test di esposizione circa 34 ms per una singola pagina) e lo ha fatto il trucco!

Sto rispondendo alla mia domanda. Spero che questo almeno aiuta qualcun altro che si imbatte in questo problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top