为图片框中的每个像素绘制颜色
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 产生的颜色。
注意:我假设您绘制的是方形位图。绘制成矩形需要更多的工作。同样的事情适用于不同的尺寸。
谁能帮帮我:我想把每个像素的颜色都画到 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 产生的颜色。 注意:我假设您绘制的是方形位图。绘制成矩形需要更多的工作。同样的事情适用于不同的尺寸。