Tôi có một chương trình vẽ nhỏ mà tôi đang làm việc. Tôi đang sử dụng SetPixel trên một bitmap để vẽ bản vẽ đó. Khi kích thước bàn chải lớn, như 25 điểm ảnh trên đó là một hiệu suất đáng chú ý thả. Tôi tự hỏi nếu có một cách nhanh hơn để vẽ một bitmap. Dưới đây là một chút nền của dự án:SetPixel quá chậm. Có cách nào nhanh hơn để vẽ lên bitmap không?
- Tôi đang sử dụng bitmap để tôi có thể sử dụng các lớp, như trong Photoshop hoặc GIMP.
- Các dòng đang được vẽ theo cách thủ công vì điều này cuối cùng sẽ sử dụng áp lực của máy tính bảng đồ họa để thay đổi kích thước của đường theo chiều dài của nó.
- Các dòng cuối cùng sẽ được chống xung/làm mịn dọc theo các cạnh.
Tôi sẽ bao gồm mã vẽ của mình trong trường hợp nó chậm và không phải là bit Set-Pixel.
này nằm trong cửa sổ nơi bức tranh sẽ xảy ra:
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
m_lastPosition = m_currentPosition;
m_currentPosition = e.Location;
if(m_penDown && m_pointInWindow)
m_currentTool.MouseMove(m_lastPosition, m_currentPosition, m_layer);
canvas.Invalidate();
}
Thực hiện MouseMove:
public override void MouseMove(Point lastPos, Point currentPos, Layer currentLayer)
{
DrawLine(lastPos, currentPos, currentLayer);
}
Thực hiện DrawLine:
// The primary drawing code for most tools. A line is drawn from the last position to the current position
public override void DrawLine(Point lastPos, Point currentPos, Layer currentLayer)
{
// Creat a line vector
Vector2D vector = new Vector2D(currentPos.X - lastPos.X, currentPos.Y - lastPos.Y);
// Create the point to draw at
PointF drawPoint = new Point(lastPos.X, lastPos.Y);
// Get the amount to step each time
PointF step = vector.GetNormalisedVector();
// Find the length of the line
double length = vector.GetMagnitude();
// For each step along the line...
for (int i = 0; i < length; i++)
{
// Draw a pixel
PaintPoint(currentLayer, new Point((int)drawPoint.X, (int)drawPoint.Y));
drawPoint.X += step.X;
drawPoint.Y += step.Y;
}
}
Thực hiện PaintPoint:
public override void PaintPoint(Layer layer, Point position)
{
// Rasterise the pencil tool
// Assume it is square
// Check the pixel to be set is witin the bounds of the layer
// Set the tool size rect to the locate on of the point to be painted
m_toolArea.Location = position;
// Get the area to be painted
Rectangle areaToPaint = new Rectangle();
areaToPaint = Rectangle.Intersect(layer.GetRectangle(), m_toolArea);
// Check this is not a null area
if (!areaToPaint.IsEmpty)
{
// Go through the draw area and set the pixels as they should be
for (int y = areaToPaint.Top; y < areaToPaint.Bottom; y++)
{
for (int x = areaToPaint.Left; x < areaToPaint.Right; x++)
{
layer.GetBitmap().SetPixel(x, y, m_colour);
}
}
}
}
Cảm ơn rất nhiều sự giúp đỡ nào bạn có thể cung cấp.
Cảm ơn vì điều này. Tôi nghĩ rằng tôi thấy những gì đang xảy ra; ptr là một khối dữ liệu bitmap chứa các giá trị pixel màu đỏ, xanh lá cây và xanh lam và được đặt theo cách thủ công. Tôi sẽ thực hiện việc này ngay hôm nay và xem cách hoạt động. Cảm ơn rất nhiều vì điều này, tôi cảm thấy sự hiểu biết của mình đã nâng cao một khía cạnh khác: P Chỉ một điều, tôi nghĩ bitmap trong C# cũng có kênh alpha. Tôi nghĩ rằng điều này sẽ được xử lý trong thông tin màu pixel cùng với RGB. – Pyro
Bạn cần chỉ định http://msdn.microsoft.com/en-us/library/system.drawing.imaging.pixelformat.aspx để bao gồm thành phần alpha. Chỉ cần thay đổi 'PixelFormat.Format24bppRgb' thành' PixelFormat.Format32bppArgb'. Tôi tin rằng nó nên được sau khi R vì vậy chỉ cần bù đắp nó bằng cách +3. Nếu bạn sử dụng 32 bit cho mỗi pixel, bạn sẽ cần phải thay đổi 'x * 3' thành' x * 4' vì nó sẽ là 4 byte cho mỗi pixel ngay bây giờ. – Jack
Tôi vừa thử điều này. Nó là đáng yêu và nhanh chóng trên tất cả các kích cỡ bàn chải! Tuy nhiên hiện nay có một số hành vi kỳ lạ: Bản vẽ thực tế xảy ra ở mức bù cho vị trí của chuột. Tôi tự hỏi có liên quan gì đến dòng này không: BitmapData data = bmp.LockBits (Hình chữ nhật mới (areaToPaint.Right, areaToPaint.Bottom), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); Cần có vị trí được chỉ định cho hình chữ nhật. Tôi đã sử dụng giá trị 'vị trí' được cung cấp. Có đúng không? – Pyro