2015-04-29 4 views
2

Может кто-нибудь мне помочь: Я хочу, чтобы нарисовать цвет каждый пиксель PictureBoxDraw цвета для каждого пикселя в 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)); 
      } 
     } 
    } 

} 
} 

Я добавил таймер так я вижу прогресс в рисовании каждого пикселя.

Проблема код этого сделать в памяти - задержка - затем положить в картине поле

Я хочу сделать цвет каждую у = 0 и х = 0 до 200, у = 1 х = 0 до 200, у = 2 x = от 0 до 200 и т.д.

+0

Простым решением является три вложенных цикла для генерации диапазона всех возможных значений. Это O (n^3), но 8 миллионов итераций не так уж плохи. – jdphenix

+0

сделал это? – usr6969

+0

На самом деле можно генерировать каждый цвет между (R, B, G) = (0,200, 0,200, 0,200). Я предложил один из способов сделать это. – jdphenix

ответ

1

Каждый раз, когда ваш таймер тикает, вы хотите нарисовать другой пиксель с (разным?) Цветом, не так ли?

Что вам нужно сделать, это объявить текущие координаты x и y вне метода timer1_Tick и соответственно увеличить их значения каждый раз, когда вы рисуете что-то.

Чтобы сразу увидеть результаты, вы также должны вызвать pictureBox1.Refresh() внутри timer1_Tick(). Вот мое быстрое решение для рисования 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. Примечание: Я предположил, что вы рисуете квадратное растровое изображение. Для рисования на прямоугольник потребуется еще немного работы. То же самое относится к разным размерам.

+0

yay great это то, что я имею в виду – usr6969

+0

, как сделать скорость вытягивания быстрее? i alredy установить таймер на 1, но этого недостаточно – usr6969

0

Ваш код устанавливает каждый пиксель в один цвет.

Если, как вы написали вы хотите смотреть каждый цвет в настоящее время краситься вы должны сделать два изменения:

  • Сделать PictureBox достаточно большой, то есть 256х256 пикселей внутри (цветовое пространство RGB является 256x256x256)
  • Draw каждый пиксель с другим цветом

Вот пример:

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.

Если вы хотите смотреть каждый пиксель набор, вы бы переместить х и у, чтобы сформировать уровень и увеличивать их в 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 или событие !

Это будет работать, но он будет медленным ;-)

Чтобы повторно использовать Bitmap просто создать его за пределами Tick, может быть в конструкторе!

Если вы хотите, чтобы все пиксели имели одинаковые Color, вы не должны устанавливать пиксели один за другим.Вместо этого вы можете создать Graphics для Bitmap и использовать его для 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 действительно определит скорость, если вы не увеличите размер элемента управления.

Примечание. Цветовое пространство представляет собой трехмерное пространство, поэтому нет очевидного пути прохождения каждого цвета в низах т способ ..

Малого Заключительное примечание: Если PictureBox имеет Border вы должны установить Image к (внутренний) CientSize не к (внешнему) Size!

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

thx pals для ur help – usr6969

Смежные вопросы