2012-03-08 9 views
6

Sto lavorando a un programma in C# che cattura screenshot di una pozione dello schermo dell'utente. Per la maggior parte del pert funziona come dovrebbe, ma recentemente ho incontrato un problema. Sembra esserci (almeno) un colore di pixel che appare sempre trasparente nell'immagine di output. Qualsiasi istanza del colore # 0D0B0C (RGB 13, 11, 12) appare trasparente nella png salvata. Questo è con PixelFormat impostato su Format32bppArgb. Se lo metto in Format32bppRgb o Format24bppRgb, quello stesso pixel appare nero nel png salvato.Oggetto bitmap C#, il colore appare trasparente

Non ho idea di cosa potrebbe causare questo, ma l'unica cosa che sono stato in grado di fare per "risolvere" è quello di cancellare l'oggetto grafico a quel colore prima di fare CopyFromScreen(). Sono dispiaciuto di farlo anche se per pochi motivi. Innanzitutto, non so se questo è l'unico colore che presenta il problema (con 16.777.216 colori ci sono un bel po 'di possibilità), e in secondo luogo, io odio le correzioni di hacking, questa sembra una correzione di hacking.

Qualcuno può far luce su ciò che potrebbe causare questo problema? Ho incasinato PixelFormat nella creazione di bitmap e con CopyPixelOperation nel metodo CopyFromScreen, niente sembra funzionare. Il fatto che cancellare l'oggetto grafico con quel colore "corregge" sembra dirmi che la trasparenza proviene dai dati dello schermo stesso, ma questo non ha senso. Sono stato a guardare questo per troppo tempo, penso che ho bisogno di una nuova prospettiva su di esso. Se qualcuno ha qualche idea del perché questo potrebbe accadere mi piacerebbe sentirlo. Grazie.

risposta

-2

Sembra che tu abbia dei pixel difettosi sullo schermo.

+2

Tutto quello che devi fare per diagnosticare è spostare il modulo sullo schermo e vedere se va via. Dubito molto seriamente che questo è il problema ... –

+0

È più pixel e accade su più schermi/computer diversi, ed è sempre solo quel colore. Pensavo che il problema fosse risolto ma uno degli utenti del programma mi ha detto che stava ancora accadendo. – HaLo2FrEeEk

1

Il valore alfa è forse 0? L'hai controllato?

Poiché il grande diverso tra Format32bppArgb e Format32bppRgb è che il secondo formato non conosce il canale alfa.

+0

Una schermata di stampa restituisce un'immagine corretta e, come ho detto nell'OP, quando l'ho impostata su Format32bppRgb, gli stessi pixel appaiono neri (quando dovrebbero essere # 0D0B0C). Nessuno degli altri pixel appare trasparente e questo sembra qualcosa che potrebbe essere presente anche in uno schermo di stampa. – HaLo2FrEeEk

+0

come si acquisiscono gli screenshot? – cansik

+0

Come ho detto nell'OP, utilizzo un oggetto grafico e CopyFromScreen(). – HaLo2FrEeEk

0

Aveva lo stesso identico problema quando si esegue il rendering di un controllo su una bitmap. Riuscito a risolverlo creando un'altra bitmap con PixelFormat.Format32bppRgb e BitBlting ad esso. Spero che questo ti aiuti!

public class ScreenCapture 
{ 
    [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] 
    private static extern bool BitBlt(
     IntPtr hdcDest, // handle to destination DC 
     int nXDest, // x-coord of destination upper-left corner 
     int nYDest, // y-coord of destination upper-left corner 
     int nWidth, // width of destination rectangle 
     int nHeight, // height of destination rectangle 
     IntPtr hdcSrc, // handle to source DC 
     int nXSrc, // x-coordinate of source upper-left corner 
     int nYSrc, // y-coordinate of source upper-left corner 
     System.Int32 dwRop // raster operation code 
     ); 


    /// <summary> 
    /// Returns an image of the control 
    /// </summary> 
    /// <param name="control">The control object whose image is wanted</param> 
    /// <returns>Image of the control</returns> 
    /// <remarks>This is based on code from 
    /// http://www.dotnet247.com/247reference/a.aspx?u=http://www.c-sharpcorner.com/Code/2002/April/ScreenCaptureUtility.asp 
    /// with changes made to prevent 0D0B0C transparency issues</remarks> 
    public static Image GetControlImage(Control control) 
    { 
     Graphics g1 = control.CreateGraphics(); 

     // Create a bitmap the same size as the control 
     Image MyImage = new Bitmap(control.ClientRectangle.Width, control.ClientRectangle.Height, PixelFormat.Format32bppRgb); 
     (MyImage as Bitmap).SetResolution(g1.DpiX, g1.DpiY); 

     Graphics g2 = Graphics.FromImage(MyImage); 

     IntPtr dc1 = g1.GetHdc(); 
     IntPtr dc2 = g2.GetHdc(); 

     // BitBlt from one DC to the other 
     BitBlt(dc2, 0, 0, control.ClientRectangle.Width, control.ClientRectangle.Height, dc1, 0, 0, 13369376); 

     // Release Device Contexts 
     g1.ReleaseHdc(dc1); 
     g2.ReleaseHdc(dc2); 

     // This statement runs the garbage collector manually 
     // (If not present, uses up large amounts of memory...) 
     GC.Collect(); 

     return MyImage; 
    } 
} 
0

semplicemente dovuto chiedere il CopyFromScreen in un bitmap che non ha un canale alfa a tutti, come ad esempio:

Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height,  System.Drawing.Imaging.PixelFormat.Format32bppRgb); 
Graphics graphics = Graphics.FromImage(bitmap as Image); 
graphics.CopyFromScreen(bounds.Location, new Point(0, 0), bitmap.Size); 

ho confermato che questo ha fori di pixel trasparenti con Format32bppArgb ma non con Format32bppRgb

Problemi correlati