Windows Forms'da tek bir piksel çizin


94

Bir Windows Formunda tek bir pikseli açmaya çalışırken takılıp kaldım.

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

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

API gerçekten bir pikselin rengini ayarlamak için bir yönteme sahip olmalı, ancak ben bir tane görmüyorum.

C # kullanıyorum.


Bazı çok güzel bilimsel grafikleri çizen bir kontrol yaptım (ek yeteneklerle herhangi bir ticari kontrolde bulunmam gerekmiyor). Bir veri noktasını ve X veya a + veya küçük bir kutu ile çizebilirim. Ama önemsiz veriler için sadece tek bir piksel istiyorum.
Mark T

Gördüğüm tüm cevaplar tek bir piksel için gerçekten fazla mı? Sadece arabellek [y * genişlik + x] = renk yapmak neden daha kolay görünüyor;
NoMoreZealots

Yanıtlar:


114

Bu, tek bir piksel ayarlayacaktır:

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

18
DrawRectangle'ın 2x2 çizdiğini ancak FillRectange'in aynı argümanlarla 1x1 çizdiğini kim tahmin edebilirdi? Teşekkürler.
Mark T

9
@Mark: Bu bir anlam ifade ediyor ... DrawRectangle "bu genişlik ve yükseklikte x ve y'den başlayan bir anahat çizin" diyor, böylece hem başlangıç ​​hem de bitiş noktalarını (x, y; x + 1, y ; x, y + 1; x + 1, y + 1) ve aralarındaki çizgiler. FillRectangle "bu genişlik ve yükseklikte x, y'den başlayan katı bir yüzey çizin" diyor. Bu arada, FillRectangle bir Kalem değil, Fırça alır.
Powerlord

5
@R. Bemrose: Aslında geçtiğiniz Pen nesnesine bağlıdır DrawRectangle(). Varsa , verilen dikdörtgenin çevresinde pikseller kalın bir çerçeve Pen.Alignment = PenAlignment.Outsetçizecektir Pen.Width. Ancak belirtirseniz Pen.Alignment = PenAlignment.Inset, verilen dikdörtgenin içine Pen.Width piksel kalın "dış çizgi" çizecektir.
Cipi

2
Bu çok yetersiz bir cevap. Bu, tek bir pikseli ayarlasa da, gereksinim her zaman gerçek bir piksel ayarlamak değildir. Buna ihtiyaç duyduğum her zaman, ki bu da çoğu zaman, noktanın fırçayla değil, çizgilerin çizildiği kalemle çizilmesine ihtiyacım oldu. Diğer bir deyişle, 2 pikselden daha kısa bir çizgiye ihtiyacımız var. OP'nin ihtiyaç duyduğu şeyin bu olduğundan şüpheleniyorum.
Robertt

6
Bu cevabı beğenmedim. Bu yol oldukça verimsizdir.
user626528

19

Sadece Henk Holterman cevabının tam kodunu göstermek için:

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

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

18

GraphicsBir soyutlama olduğunu ve bir vektör grafik formatını kapsayacak şekilde kullanılabilir çünkü nesne, bu yok. Bu bağlamda, tek bir piksel ayarlamak mantıklı olmaz. BitmapResim biçimi var GetPixel()ve SetPixel()fakat bir grafik üzerinde inşa nesnesi değil. Senaryonuz için, seçeneğiniz gerçekten tek seçenek gibi görünüyor çünkü genel bir grafik nesnesi için tek bir piksel ayarlamanın her şeye uyan tek bir yolu yok (ve tam olarak ne olduğunu bilmiyorsunuz, kontrolünüz / formunuz çift ​​arabelleğe alınabilir, vb.)

Neden tek bir piksel ayarlamanız gerekiyor?


9

Çok sayıda tek piksel çizdiğim yerlerde (çeşitli özelleştirilmiş veri ekranları için), onları bir bit eşleme çizme ve sonra bunu ekrana yıldırım.

Bitmap GetPixel ve SetPixel işlemleri, çok fazla sınır denetimi yaptıkları için özellikle hızlı değildir, ancak bir bitmap'e hızlı erişimi olan bir 'hızlı bitmap' sınıfı oluşturmak oldukça kolaydır.


2

GetHdc'de MSDN Sayfası

Sanırım aradığınız şey bu. SetPixel'i kullanmak için HDC'yi almanız ve ardından GDI çağrılarını kullanmanız gerekecektir. GDI'daki bir COLORREF'in, BGR rengini depolayan bir DWORD olduğuna dikkat edin. Alfa kanalı yoktur ve GDI + 'nın Renk yapısı gibi RGB değildir.

Bu, aynı görevi gerçekleştirmek için yazdığım küçük bir kod bölümü:

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

1

Görünüşe göre DrawLine, belirtilen gerçek uzunluktan bir piksel kısa bir çizgi çiziyor. Bir DrawPoint / DrawPixel / whatnot yok gibi görünüyor, ancak bunun yerine, tek bir piksel çizmek için genişlik ve yükseklik 1 olarak ayarlanmış DrawRectangle'ı kullanabilirsiniz.


2
İyi deneme, ancak boyut 1 ile 2x2 piksel çiziyor. (Bir çizginin yanına çizin ve iki kat daha geniş olduğunu görebilirsiniz.) Ve sıfır boyutuyla, elbette hiçbir şey çizmez.
Mark T

Doğru, benim hatam. :) İyi ki FillRectangle hile yapıyor.
Rytmis

0

DashStyle.DashStyle.Dot ile Kalem kullanarak Çizgi 2px çizmek, tek bir Piksel çizer.

    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);
        }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.