2009-04-17 9 views
71

Я застреваю, пытаясь включить один пиксель в Windows Form.Нарисуйте один пиксель на Windows Forms

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

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

API действительно должен иметь способ установить цвет одного пикселя, но я его не вижу.

Я использую C#.

+0

Я сделал контроль, который содержит некоторые очень хорошие научные графики (с добавленными возможностями, которые мне недоступны в любых коммерческих элементах управления). Я могу построить точку данных с и X или + или небольшую коробку. Но для несущественных данных я просто хочу один пиксель. –

ответ

94

Это установит один пиксель:

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

Кто бы мог предположить, что DrawRectangle рисует 2x2, но FillRectange рисует 1x1 с теми же аргументами? Благодарю. –

+8

@Mark: Это действительно имеет смысл ...DrawRectangle говорит: «Нарисуйте контур, начинающийся с x и y этой ширины и высоты», поэтому он рисует как начальную, так и конечную точки (x, y; x + 1, y; x, y + 1; x + 1, y + 1) и линии между ними. FillRectangle говорит: «Нарисуйте твердую поверхность, начиная с x, y этой ширины и высоты». Кстати, FillRectangle берет кисть, а не ручку. – Powerlord

+3

@R. Bemrose: На самом деле, это зависит от объекта Pen, который вы передаете 'DrawRectangle()'. Если у него есть «Pen.Alignment = PenAlignment.Outset», он нарисовал бы ширину в пикселях «Pen.Width» вокруг данного прямоугольника. Но если вы укажете «Pen.Alignment = PenAlignment.Inset», он нарисует «контур» пикселя шириной Pen.Width внутри данного прямоугольника. – Cipi

16

Объект Graphics не имеет этого, так как это абстракция и может использоваться для покрытия формата векторной графики. В этом контексте установка одного пикселя не имеет смысла. Формат изображения Bitmap имеет GetPixel() и SetPixel(), но не графический объект, построенный на одном. Для вашего сценария ваш вариант действительно кажется единственным, потому что нет единого способа установки одного пикселя для общего графического объекта (и вы не знаете ТОЧНО, что это такое, поскольку ваш элемент управления/форма может быть двухбуферизованным и т. д.)

Зачем вам нужно установить один пиксель?

1

По-видимому DrawLine рисует линию, которая на один пиксель меньше заданной длины. Кажется, что нет DrawPoint/DrawPixel/whatnot, но вместо этого вы можете использовать DrawRectangle с шириной и высотой, установленными в 1, чтобы нарисовать один пиксель.

+2

Хорошая попытка, но с размером 1 он рисует 2x2 пикселя. (Нарисуйте его рядом с линией, и вы увидите, что он вдвое шире.) И с нулевым размером, конечно, ничего не рисует. –

+0

Верно, моя ошибка. :) Хорошо, что FillRectangle делает трюк. – Rytmis

+0

Но DrawLine ничья. – Joshua

8

Где я рисую много отдельных пикселей (для различных настроенными отображения данных), я склонен рисовать их в растр, а затем блитирования, что на экране ,

Операции Bitmap GetPixel и SetPixel не особенно быстры, потому что они выполняют очень сложную проверку, но довольно легко создать класс быстрого bitmap, который имеет быстрый доступ к растровому изображению.

13

Просто, чтобы показать полный код для Henk Хольтерман ответа:

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

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

MSDN Page on GetHdc

Я думаю, что это то, что вы ищете. Вам нужно будет получить HDC, а затем использовать вызовы GDI для использования SetPixel. Обратите внимание, что COLORREF в GDI является DWORD, сохраняющим цвет BGR. Нет альфа-канала, и это не RGB, как структура цвета GDI +.

Это небольшой фрагмент кода, который я написал для выполнения той же задачи:

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

Рисование линии 2px с помощью Pen с DashStyle.DashStyle.Dot рисует один пиксель.

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); 
     } 
    } 
Смежные вопросы