为图片框中的每个像素绘制颜色

Draw color to every pixel in picturebox

谁能帮帮我:我想把每个像素的颜色都画到 picturebox

这是我目前所做的:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication25
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

    private void button1_Click(object sender, EventArgs e)
    {
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        int x, y;
        for (y = 0; y < 200; y++)
        {
            for (x = 0; x < 200; x++)
            {
                ((Bitmap)pictureBox1.Image).SetPixel(x, y, Color.FromArgb(255, 255, 0));
            }
        }
    } 

}
}

我添加了一个计时器,这样我就可以看到绘制每个像素的进度。

代码在内存中绘制的问题-延迟-然后放入图片框

我想在每个 y = 0 和 x = 0 到 200、y =1 x = 0 到 200、y=2 x=0 到 200 等范围内绘制颜色

您的代码将每个像素设置为相同的颜色。

如果,如您所写,您希望看到正在绘制的每种颜色,您应该进行两处更改:

  • 使Picturebox足够大,即里面有256x256像素 (RGB 颜色 space 为 256x256x256)
  • 用不同的颜色绘制每个像素

这是一个例子:

int blue = 0;
private void timer1_Tick(object sender, EventArgs e)
{
    // either dispose of the old Bitmap or simply reuse it!
    if (pictureBox1.Image != null) pictureBox1.Image.Dispose();
    pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
    int x, y;
    blue = (blue+1) % 256;
    Text = blue + "";
    for (y = 0; y < 256; y++)
    {
        for (x = 0; x < 256; x++)
        {
            ((Bitmap)pictureBox1.Image).SetPixel(x, y, Color.FromArgb(y, x, blue));
        }
    }
    pictureBox1.Refresh();
}

请注意,蓝色值使用 Form 级别变量并在 Tick 事件中递增。

这将为一个蓝色值绘制不同颜色的每个像素,并将遍历所有蓝色值。因此,在 256 次迭代之后,您将看到曾经存在的 RGB 颜色。

如果你想观察设置的每个像素,你可以移动 x 和 y 以形成水平并在 Tick 中递增它们,如下所示:

x = x + 1;
if (x >= 256) { x = 0; y = y + 1;}
if (y >= 256) { y = 0; x = 0; blue = blue + 1;}
((Bitmap)pictureBox1.Image).SetPixel(x, y, Color.FromArgb(x, y, blue));

而不是双循环。为此,您 需要 移动

pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);

行到例如Form 构造函数或 Form_Load 事件!

它会工作,但会很慢 ;-)

要重用 Bitmap,只需在 Tick 之外创建它,也许在构造函数中!

如果您希望所有像素都具有相同的 Color,则不应一一设置像素。相反,您可以为 Bitmap 创建一个 Graphics 并将其用于 Clear 所有像素到一种颜色:

    int argb = 255 << 24;  // we want to start with fully opaque colors!
    private void timer1_Tick(object sender, EventArgs e)
    {
       // I have move the Bitmap creation to the Form contructor
       argb += 1;
       using (Graphics G = Graphics.FromImage(pictureBox1.Image))
       {
           G.Clear(Color.FromArgb(argb));
       }

       pictureBox1.Refresh();

或者您可以简单地绘制到控件的表面:

    private void timer1_Tick(object sender, EventArgs e)
    {
       pictureBox1.Invalidate();
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        argb += 1;
        e.Graphics.Clear(Color.FromArgb(argb));
    }

这将是最快的,当然 Tick 将真正决定速度,除非您将控件的大小放大很多..

请注意颜色 space 是 3D space,因此没有明显的路径以最佳方式遍历每种颜色..

最后的小提示:如果您的 PictureBox 有一个 Border,您应该将 Image 设置为(内部)CientSize 而不是(外部)Size!

Size cs = pictureBox1.ClientSize;
pictureBox1.Image = new Bitmap(cs.Width, cs.Height); 

每次你的计时器滴答作响时,你都想用(不同的?)颜色绘制另一个像素,对吧?

您需要做的是在 timer1_Tick 方法之外声明当前的 x 和 y 坐标,并在每次绘制内容时相应地增加它们的值。

要立即查看结果,您还应该在 timer1_Tick() 中调用 pictureBox1.Refresh()。 这是我使用类似于此的模式绘制 200x200 位图的快速解决方案: All 24-bit RGB colors.

public partial class Form1 : Form
{
    private int bitmapWidth = 200;
    private int bitmapHeight = 200;
    private int currentX = 0;
    private int currentY = 0;

    public Form1()
    {
        InitializeComponent();
        pictureBox1.Image = new Bitmap(bitmapWidth, bitmapHeight);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (timer1.Enabled)
        {
            timer1.Stop();
        }
        else
        {
            timer1.Start();
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        double partWidth = (bitmapWidth / (double)16);
        int r = (int)(255 * currentX / partWidth) % 256;
        int g = (int)(255 * (currentY % partWidth) / partWidth) % 256;
        int b = (int)(Math.Floor(currentX / partWidth) + Math.Floor(currentY / partWidth) * 16);

        ((Bitmap)pictureBox1.Image).SetPixel(currentX, currentY, Color.FromArgb(r, g, b));
        pictureBox1.Refresh();
        if (currentX < bitmapWidth - 1)
        {
            currentX++;
        }
        else if (currentY < bitmapHeight - 1)
        {
            currentX = 0;
            currentY++;
        }
        else
        {
            timer1.Stop();
        }
    }
}

您可以更改通过计算 currentX、currentY 和 partWidth 产生的颜色。 注意:我假设您绘制的是方形位图。绘制成矩形需要更多的工作。同样的事情适用于不同的尺寸。