2009-04-17 21 views
71

Estoy atascado tratando de activar un solo píxel en Windows Form.Dibuje un solo píxel en Windows Forms

graphics.DrawLine(Pens.Black, 50, 50, 51, 50); // draws two pixels 

graphics.DrawLine(Pens.Black, 50, 50, 50, 50); // draws no pixels 

La API realmente debería tener un método para establecer el color de un píxel, pero no veo uno.

Estoy usando C#.

+0

Realicé un control que traza algunos gráficos científicos muy agradables (con capacidades adicionales que no necesito en ningún control comercial). Puedo trazar un punto de datos con X y a + o una pequeña caja. Pero para datos sin importancia, solo quiero un solo píxel. –

Respuesta

94

Esto establecerá un único píxel:

e.Graphics.FillRectangle(aBrush, x, y, 1, 1); 
+8

¿Quién hubiera adivinado que DrawRectangle dibuja un 2x2 pero FillRectange dibuja un 1x1 con los mismos argumentos? Gracias. –

+8

@Mark: Tiene una especie de sentido ...DrawRectangle dice "dibuja un contorno que comience en xey de este ancho y alto", por lo que dibuja los puntos de inicio y final (x, y; x + 1, y; x, y + 1; x + 1, y + 1) y líneas entre ellos. FillRectangle dice "dibujar una superficie sólida comenzando en x, y de este ancho y alto". Por cierto, FillRectangle toma un Pincel, no un Pen. – Powerlord

+3

@R. Bemrose: en realidad, depende del objeto Pen que pases a 'DrawRectangle()'. Si tiene 'Pen.Alignment = PenAlignment.Outset' dibujará un contorno grueso de 'Pen.Width' alrededor del rectángulo dado. Pero si especifica 'Pen.Alignment = PenAlignment.Inset' dibujará Pen.Width pixels thick" outline "dentro del rectángulo dado. – Cipi

16

El objeto Graphics no tiene esto, ya que es una abstracción y podría utilizarse para cubrir un formato de gráficos vectoriales. En ese contexto, establecer un solo píxel no tendría sentido. El formato de imagen Bitmap tiene GetPixel() y SetPixel(), pero no un objeto de gráficos creado en uno. Para su escenario, su opción realmente parece ser la única porque no hay una forma única de ajustar un solo píxel para un objeto gráfico general (y usted no sabe EXACTAMENTE cuál es, como su control/forma podría ser de doble amortiguamiento, etc.)

¿Por qué necesita establecer un solo píxel?

1

Aparentemente DrawLine dibuja una línea que tiene un píxel por debajo de la longitud real especificada. No parece haber un DrawPoint/DrawPixel/whatnot, pero en su lugar puede usar DrawRectangle con ancho y alto establecidos en 1 para dibujar un solo píxel.

+2

Buen intento, pero con el tamaño 1 dibuja 2x2 píxeles. (Tíralo al lado de una línea, y puedes ver que tiene el doble de ancho). Y con el tamaño cero, por supuesto, no saca nada. –

+0

Correcto, mi error. :) Lo bueno FillRectangle hace el truco. – Rytmis

+0

Pero DrawLine se queda corto. – Joshua

8

Dónde estoy dibujando un montón de píxeles individuales (por varias pantallas de datos personalizadas), tiendo a atraerlos a un mapa de bits y luego blit que en la pantalla .

Las operaciones Bitmap GetPixel y SetPixel no son particularmente rápidas porque hacen una gran cantidad de chequeo de límites, pero es bastante fácil crear una clase 'bitmap rápido' que tenga acceso rápido a un mapa de bits.

13

sólo para mostrar código completo de respuesta Henk Holterman:

Brush aBrush = (Brush)Brushes.Black; 
Graphics g = this.CreateGraphics(); 

g.FillRectangle(aBrush, x, y, 1, 1); 
0

MSDN Page on GetHdc

creo que esto es lo que busca. Necesitará obtener el HDC y luego usar las llamadas GDI para usar SetPixel. Tenga en cuenta que un COLORREF en GDI es un DWORD que almacena un color BGR. No hay un canal alfa, y no es RGB como la estructura de Color de GDI +.

Esta es una pequeña sección de código que he escrito para llevar a cabo la misma tarea:

public class GDI 
{ 
    [System.Runtime.InteropServices.DllImport("gdi32.dll")] 
    internal static extern bool SetPixel(IntPtr hdc, int X, int Y, uint crColor); 
} 

{ 
    ... 
    private void OnPanel_Paint(object sender, PaintEventArgs e) 
    { 
     int renderWidth = GetRenderWidth(); 
     int renderHeight = GetRenderHeight(); 
     IntPtr hdc = e.Graphics.GetHdc(); 

     for (int y = 0; y < renderHeight; y++) 
     { 
      for (int x = 0; x < renderWidth; x++) 
      { 
       Color pixelColor = GetPixelColor(x, y); 

       // NOTE: GDI colors are BGR, not ARGB. 
       uint colorRef = (uint)((pixelColor.B << 16) | (pixelColor.G << 8) | (pixelColor.R)); 
       GDI.SetPixel(hdc, x, y, colorRef); 
      } 
     } 

     e.Graphics.ReleaseHdc(hdc); 
    } 
    ... 
} 
0

Dibujar una línea 2px utilizando una pluma con DashStyle.DashStyle.Dot dibuja un solo píxel.

private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     using (Pen p = new Pen(Brushes.Black)) 
     { 
      p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; 
      e.Graphics.DrawLine(p, 10, 10, 11, 10); 
     } 
    }