2009-03-23 11 views
6

OK, ho un'immagine proveniente da un'applicazione esterna in un formato indicizzato a 8 bit. Ho bisogno di questa immagine convertita in un formato a 24 bit della stessa identica dimensione.Conversione da un Format8bppIndexed a un Format24bppRgb in C#/GDI +

Ho provato a creare un nuovo Bitmap delle stesse dimensioni e del tipo Format24bppRgb e quindi utilizzare un oggetto Graphics per disegnare l'immagine a 8 bit su di esso prima di salvarlo come Bmp. Questo approccio non genera errori, ma quando apro l'immagine risultante l'intestazione BMP ha tutti i tipi di valori funky. L'altezza e la larghezza sono ENORME e, inoltre, ci sono valori divertenti (e grandi) per i flag di compressione e pochi altri. Sfortunatamente le mie particolari esigenze sono di passare questo file a uno specifico driver di stampa che richiede un'immagine a 24 bit con valori di intestazione specifici (che sto cercando di ottenere tramite GDI +)

Qualcuno sa di un esempio su "up- convertire "un file indicizzato in un file a 24 bit non indicizzato? Se non un esempio, quale percorso dovrei iniziare a scrivere il mio?

-Kevin Grossnicklaus [email protected]

risposta

0

Sembra strano che si sta creando un bitmap della stessa larghezza e l'altezza come ingresso, eppure il BMP generato è molto più grande. Puoi pubblicare del codice?

0

Il problema è probabilmente la differenza tra la risoluzione verticale e orizzontale dell'immagine sorgente e l'immagine di uscita. Se si carica una bitmap con indice 8bpp con una risoluzione di 72 DPI, e quindi si crea una nuova bitmap 24bpp (la risoluzione predefinita sarà 96 DPI ... almeno è sul mio sistema) e quindi si usa Graphics.DrawImage per blittare al nuovo bitmap, l'immagine apparirà leggermente ingrandita e ritagliata.

Detto questo, io non conosco la parte superiore della mia testa come correttamente creare la bitmap di uscita e/o oggetto Graphics per scalare correttamente quando salvato. Sospetto che abbia qualcosa a che fare con la creazione delle immagini usando una scala comune come i pollici invece dei pixel.

11

Ho utilizzato il seguente codice per "convertire" un'immagine da 8bpp a 24bpp. L'ispezione del file 24bpp generato con un editor esadecimale e il confronto con il file 8bpp non mostrano differenze di altezza e larghezza nei due file. Cioè, l'immagine 8bpp era 1600x1200 e l'immagine 24bpp ha gli stessi valori.

private static void ConvertTo24(string inputFileName, string outputFileName) 
    { 
     Bitmap bmpIn = (Bitmap)Bitmap.FromFile(inputFileName); 

     Bitmap converted = new Bitmap(bmpIn.Width, bmpIn.Height, PixelFormat.Format24bppRgb); 
     using (Graphics g = Graphics.FromImage(converted)) 
     { 
      // Prevent DPI conversion 
      g.PageUnit = GraphicsUnit.Pixel 
      // Draw the image 
      g.DrawImageUnscaled(bmpIn, 0, 0); 
     } 
     converted.Save(outputFileName, ImageFormat.Bmp); 
    } 

Tutto il resto nelle intestazioni sembra ragionevole e le immagini visualizzate sono identiche sul mio sistema. Quali "valori funky" stai vedendo?

+1

Si consiglia di includere g.PageUnit = GraphicsUnit.Pixel per garantire che essa trae pixel per pixel, piuttosto che fare la conversione DPI (che DrawImage fa di default). –

+0

@ Chris: Grazie per il suggerimento. Lo aggiungerò –

+0

@Jim: Vorrei aggiungere che il suggerimento di erlando per impostare la risoluzione a volte è necessario per assicurarsi che il risultato sia davvero invariato (oggi ho colpito questo caso). –

4

Questo è il mio codice di conversione. Notare la corrispondenza della risoluzione tra l'immagine sorgente e l'immagine risultante.

private void ConvertTo24bppPNG(Stream imageDataAsStream, out byte[] data) 
    { 
     using (Image img = Image.FromStream(imageDataAsStream)) 
     { 
      using (Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb)) 
      { 
       // ensure resulting image has same resolution as source image 
       // otherwise resulting image will appear scaled 
       bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution); 

       using (Graphics gfx = Graphics.FromImage(bmp)) 
       { 
        gfx.DrawImage(img, 0, 0); 
       } 

       using (MemoryStream ms = new MemoryStream()) 
       { 
        bmp.Save(ms, ImageFormat.Png); 
        data = new byte[ms.Length]; 
        ms.Position = 0; 
        ms.Read(data, 0, (int) ms.Length); 
       } 
      } 
     } 
    }