Draw color to every pixel in picturebox
Solution 1
Each time your timer ticks you want to draw another pixel with (different?) color, right?
What you need to do is declare current x and y coordinates outside of timer1_Tick method and increase their values accordingly every time you draw something.
To immediately see the results you should also call pictureBox1.Refresh() inside timer1_Tick(). Here's my quick solution to draw 200x200 bitmap with a pattern similar to this: 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();
}
}
}
You can alter colors produced by calculating them off of currentX, currentY and partWidth. Note: I assumed you draw a square bitmap. Drawing to a rectangle would require some more work. Same thing applies to different sizes.
Solution 2
Your code sets each pixel to the same color.
If, as you wrote you want to watch every color is being be painted you should make two changes:
- Make the Picturebox large enough, ie 256x256 pixels inside (RGB color space is 256x256x256)
- Draw every pixel with a different color
Here is an example:
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();
}
Note that is uses a Form
level variable for the blue value and increments it in the Tick
event.
This will draw each pixel in a different color for one value of Blue and will iterate over all values for blue. So after 256 iteration you will ahve seen ever RGB color there is.
If you want to watch each pixel being set, you would move x and y to form level and increment them in the Tick
like this:
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));
instead of the double loop. For this to work you need to move the
pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
line to e.g. the Form
constructor or the Form_Load
event!
It will work but it will be slow ;-)
To reuse the Bitmap
simply create it outside of the Tick
, maybe in the constructor!
If instead you want all pixels to have the same Color
you should not set the pixels one by one. Instead you can create a Graphics
for the Bitmap
and use it to Clear
all pixels to one Color:
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();
Or you could simply draw to the surface of the control:
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));
}
This would be the fastest, except that of course the Tick will really determine the speed, unless you enlarge the size of the control a lot..
Note the Color space is a 3D space, so there is no obvious path to go through each color in the nicest way..
Small final note: If your PictureBox
has a Border
you should set the Image
to the (inner) CientSize
not to the (outer) Size
!
Size cs = pictureBox1.ClientSize;
pictureBox1.Image = new Bitmap(cs.Width, cs.Height);
usr6969
Updated on June 04, 2022Comments
-
usr6969 almost 2 years
Can someone help me: I want to draw colors every pixel to picturebox
This is what I have done so far:
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)); } } } } }
I have added a Timer so i can see the progress in drawing every pixel.
The problem the code do draw in memory - delay - then put in picture box
I want draw color every y = 0 and x = 0 to 200 , y =1 x = 0 to 200, y=2 x=0 to 200 etc
-
usr6969 almost 9 yearsyay great this is what i mean
-
usr6969 almost 9 yearshow to make the draw speed more quickly?? i alredy set timer to 1 but it's not enough