2012-03-08 13 views
6

Estoy trabajando en un programa en C# que toma capturas de pantalla de una poción de la pantalla del usuario. Para los más exigentes funciona como debería, pero recientemente me encontré con un problema. Parece haber (al menos) un color de píxel que siempre aparece como transparente en la imagen de salida. Cualquier instancia del color # 0D0B0C (RGB 13, 11, 12) aparece transparente en el png guardado. Esto es con PixelFormat establecido en Format32bppArgb. Si lo configuro en Format32bppRgb o Format24bppRgb, ese mismo color de píxel aparece como negro en el png guardado.C# Bitmap objeto, el color aparece como transparente

No tengo idea de qué podría estar causando esto, pero lo único que he podido hacer para "arreglarlo" es borrar el objeto gráfico a ese color antes de hacer CopyFromScreen(). Aunque odio eso, por algunas razones. Primero, no sé si ese es el único color que tiene el problema (con 16,777,216 colores hay bastantes posibilidades), y segundo, odio las soluciones de hack, esto parece una solución de hackeo.

¿Alguien puede arrojar alguna luz sobre lo que podría estar causando este problema? Me he metido con PixelFormat en la creación del mapa de bits y con CopyPixelOperation en el método CopyFromScreen, nada parece funcionar. El hecho de que borrar el objeto gráfico de ese color "corrige" parece decirme que la transparencia proviene de los datos de la pantalla en sí, pero eso no tiene sentido. He estado mirando esto por mucho tiempo, creo que necesito una nueva perspectiva al respecto. Si alguien tiene alguna idea de por qué esto podría estar pasando, me encantaría escucharlo. Gracias.

Respuesta

-2

Parece que tiene un píxel defectuoso en la pantalla.

+2

Todo lo que tienes que hacer para diagnosticar es mover el formulario en la pantalla y ver si se va. Dudo mucho que ese sea el problema ... –

+0

Tiene múltiples píxeles y ocurre en múltiples pantallas/computadoras diferentes, y siempre es solo ese color. Pensé que el problema estaba solucionado, pero uno de los usuarios del programa me dijo que todavía estaba sucediendo. – HaLo2FrEeEk

1

¿El valor alfa es quizás 0? ¿Lo has comprobado?

Porque la gran diferencia entre Format32bppArgb y Format32bppRgb es que el segundo formato no conoce el canal alfa.

+0

Una pantalla de impresión da como resultado una imagen que es correcta, y como dije en el OP, cuando lo configuré en Format32bppRgb, los mismos píxeles aparecen en negro (cuando deberían ser # 0D0B0C). Ninguno de los otros píxeles parece transparente, y esto suena como algo que también estaría presente en una pantalla de impresión. – HaLo2FrEeEk

+0

¿cómo captura sus capturas de pantalla? – cansik

+0

Como dije en el PO, utilizo un objeto gráfico y CopyFromScreen(). – HaLo2FrEeEk

0

Tuve exactamente el mismo problema al renderizar un control en un mapa de bits. Se las arregló para arreglarlo creando otro mapa de bits con PixelFormat.Format32bppRgb y BitBlt'ing a él. ¡Espero que esto ayude!

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

simplemente tenía que solicitar la CopyFromScreen en un mapa de bits que no tiene un canal alfa en absoluto, como por ejemplo:

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); 

Me confirmado que tiene agujeros de píxeles transparentes con Format32bppArgb pero no con Format32bppRgb

Cuestiones relacionadas