2016-03-19 7 views
1

Я использую элемент управления PictureBox для рисования сложных диаграмм, а для оптимизации производительности я использую кэш-растровое изображение для каждого слоя чертежа и рисую его на управляющем изображении, верхние слои имеют прозрачный фоны, мне нужно очистить их и перерисовать при каждом изменении.Очистить растровое изображение .Net

Предполагает, что g-пример класса Graphics растрового изображения, используя g.Clear(Color.White), рисует белый прямоугольник над всем и таким образом скрывает нижние слои, а g.Clear(Color.Transparent) рисует прозрачный прямоугольник над, что значит ничего не делать.

Не существует способа очистить битмап, возвращая его в исходное состояние?

+0

Если они не меняются так часто, я бы рассмотрел возможность рисования нижних уровней в растровое изображение, которое я показываю как PictureBox.Image или даже BackgroundImage. Помимо того, что я не делаю, существует способ рисовать все растровые изображения, которые составляют общее изображение, когда кто-либо меняется. Однако вы можете кэшировать не только отдельные слои, но и их композиты; но вам все равно нужно будет воссоздать все растровые изображения с измененного слоя вверх. - Btwe: Я не уверен в вашем выборе слова: похоже, вы не столько спрашиваете об очистке __Bitmap__, но и от частей или всей вашей составной графики? – TaW

+0

всякий раз, когда происходит изменение (скажем, движение), я повторно рисую фигуры в слое, где изменение (после очистки его цветом фона) на изображении его кеша слоя, затем рисуйте изображения всех слоев вниз вверх на картинке .image, при очистке изображения слоя с любым цветом, отличным от «прозрачного», это нормально, но если слой прозрачен (потому что это слой перекрытия), перемещенная фигура по-прежнему выполняется в обеих позициях (старая и новая). –

+0

Давайте сделаем это ясно: вы рисуете все эти слои на вершине одного pb? не изображение? нет вложенных панелей? (которые являются хорошим способом избежать большей перерисовки ..) – TaW

ответ

1

Возможно, это не тот ответ, который вы искали, но я думаю, что это альтернативная альтернатива тому, что у вас есть.

Вместо того, чтобы привлечь все слои вверх от каждого изменения, укладываю в несколько слоев друг на друга вложенности ряда PictureBoxes в один нижний PictureBox pBox0:

List<PictureBox> Layers = new List<PictureBox>(); 

private void Form1_Load(object sender, EventArgs e) 
{ 
    Layers.Add(pBox0); 
    setUpLayers(pBox0 , 20); // stacking 20 layers onto the botton one 
    timer1.Start();   // simulate changes 
} 

штабелирование является настроить так:

void setUpLayers(Control parent, int count) 
{ 
    for (int i = 0; i < count; i++) 
    { 
     PictureBox pb = new PictureBox(); 
     pb.BorderStyle = BorderStyle.None; 
     pb.Size = parent.ClientSize; 
     Bitmap bmp = new Bitmap(pb.Size.Width,pb.Size.Height,PixelFormat.Format32bppPArgb); 
     pb.Image = bmp; 
     pb.Parent = i == 0 ? pBox0 : Layers[i - 1]; 
     Layers.Add(pb); 
    } 
} 

Для лучшей производительности я использую Format32bppPArgb как формат пикселя.

Для тестирования я бегу Tick событие, которое случайным образом черпает на слой:

Random R = new Random(9); 
private void timer1_Tick(object sender, EventArgs e) 
{ 
    int l = R.Next(Layers.Count-1) + 1; 

    Bitmap bmp = (Bitmap) Layers[l].Image; 
    using (Graphics G = Graphics.FromImage(Layers[l].Image)) 
    { 
     G.Clear(Color.Transparent); 
     using (Font font = new Font("Consolas", 33f)) 
     G.DrawString(l + " " + DateTime.Now.Second , font, Brushes.Gold, 
      R.Next(bmp.Size.Width), R.Next(bmp.Size.Height)); 
    } 
    Layers[l].Image = bmp; 
} 

Чтобы собрать все слои в один растр вы бы использовать DrawToBitmap метода:

Bitmap GetComposite(Control ctl) 
{ 
    Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height, 
          PixelFormat.Format32bppArgb); 
    ctl.DrawToBitmap(bmp, ctl.ClientRectangle); 
    return bmp; 
} 

Результат могут быть сохранены или использованы любым другим способом.

Обратите внимание, что создание слишком большого количества слоев таким образом превзойдет границы оконных ручек; Я ударил этот предел около 90 слоев. Если вам нужно больше, чем несколько десятков слоев, требуется более сложная стратегия кэширования.