Привет в зависимости от темы: Как динамически создать изображение jpg в памяти с помощью .NET?
У меня есть этот метод:
int maxVal = 50;
int maxXCells = r.Next(maxVal);
int maxYCells = r.Next(maxVal);
int cellXPosition = r.Next(maxVal);
int cellYPosition = r.Next(maxVal);
int boxSize = 10;
Graphics fg = this.CreateGraphics();
using (var bmp = new System.Drawing.Bitmap(maxXCells * boxSize + 1, maxYCells * boxSize + 1))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.Yellow);
Pen pen = new Pen(Color.Black);
pen.Width = 1;
//Draw red rectangle to go behind cross
Rectangle rect = new Rectangle(boxSize * (cellXPosition - 1), boxSize * (cellYPosition - 1), boxSize, boxSize);
g.FillRectangle(new SolidBrush(Color.Red), rect);
//Draw cross
g.DrawLine(pen, boxSize * (cellXPosition - 1), boxSize * (cellYPosition - 1), boxSize * cellXPosition, boxSize * cellYPosition);
g.DrawLine(pen, boxSize * (cellXPosition - 1), boxSize * cellYPosition, boxSize * cellXPosition, boxSize * (cellYPosition - 1));
//Draw horizontal lines
for (int i = 0; i <= maxXCells; i++)
{
g.DrawLine(pen, (i * boxSize), 0, i * boxSize, boxSize * maxYCells);
}
//Draw vertical lines
for (int i = 0; i <= maxYCells; i++)
{
g.DrawLine(pen, 0, (i * boxSize), boxSize * maxXCells, i * boxSize);
}
}
fg.DrawImage(bmp, 0, 0);
fg.Dispose();
}
Он срабатывает на основе случайного события (может быть много раз в секунду). Что я должен сделать, чтобы нарисовать новое изображение только после того, как текущий рисунок закончен? В настоящий момент я вижу, что если событие для запуска этого метода срабатывает быстрее, чем завершилось рисование, экран мерцает. Каково общее решение, позволяющее избежать рисования до завершения предыдущего рисунка?
Это то, что я включил в метод OnPaint:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs pe)
{
finishedInvalidating = false;
fg = this.CreateGraphics();
lock (bmp)
{
fg.DrawImage(bmp, 0, 0);
}
fg.Dispose();
finishedInvalidating = true;
Но это не решает проблему
---------------------- обновление ------------------
public partial class LadderFrm : Form
{
Bitmap bmp;
int numCols = 3;
int colWidth = 100;
int numRows = 30;
int rowHeight = 20;
bool finishedInvalidating = false;
decimal lastprice;
public LadderFrm()
{
bmp = new System.Drawing.Bitmap(numCols * colWidth + 1, numRows * rowHeight + 1);
prepareLadderGraphics();
}
// prepare initial ladder background
private void prepareLadderGraphics()
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.LightGray);
Pen pen = new Pen(Color.Black);
pen.Width = 1;
// drawCells
for (int i = 0; i < numCols; i++)
{
for (int j = 0; j < numRows; j++)
{
Rectangle rect = new Rectangle(i * colWidth, j * rowHeight, colWidth, rowHeight);
g.DrawRectangle(pen, rect);
}
}
g.Dispose();
}
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs pe)
{
Graphics fg = this.CreateGraphics();
lock (fg)
{
lock (bmp)
{
fg.DrawImage(bmp, 0, 0);
}
}
fg.Dispose();
}
public void OrderBookUpdateFn(OrderBookEvent orderBookEvent)
{
if (lastprice != orderBookEvent.ValuationAskPrice)
{
lastprice = orderBookEvent.ValuationAskPrice;
lock (bmp)
{
using (Graphics g = Graphics.FromImage(bmp))
{
Pen pen = new Pen(Color.Black);
pen.Width = 1;
for (int i = 0; i < numRows; i++)
{
Rectangle rect = new Rectangle(colWidth + 1, i*rowHeight + 1, colWidth - 1, rowHeight - 1);
g.FillRectangle(new SolidBrush(Color.LightGray), rect);
g.DrawString(lastPrice.ToString(), new Font(FontFamily.GenericSansSerif, 10), new SolidBrush(Color.Black), new Point(colWidth + 1, i*rowHeight + 1));
}
g.Dispose();
}
this.Invalidate(new Rectangle(0, 0, 1, 1));
}
}
}
Вышеупомянутый код работает, довольно хорошо, однако я не уверен, правильно ли он. Это только для целей теста. Метод OrderBookUpdateFn (OrderBookEvent orderBookEvent) срабатывает очень часто (иногда десятки раз в секунду).