gpt4 book ai didi

c# - SetPixel 太慢了。有没有更快的方法来绘制位图?

转载 作者:可可西里 更新时间:2023-11-01 08:19:19 27 4
gpt4 key购买 nike

我正在开发一个小型绘图程序。我在位图上使用 SetPixel 来绘制线条。当画笔尺寸变大时,例如 25 像素,性能会明显下降。我想知道是否有更快的方法来绘制位图。以下是该项目的一些背景:

  • 我使用位图是为了可以利用图层,例如在 Photoshop 或 The GIMP 中。
  • 线条是手动绘制的,因为这最终会使用绘图板压力来改变线条长度的大小。
  • 线条最终应该沿边缘消除锯齿/平滑。

我将包括我的绘图代码以防万一它是缓慢的而不是 Set-Pixel 位。

这是在绘画发生的窗口中:

    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();
}

MouseMove 的实现:

    public override void MouseMove(Point lastPos, Point currentPos, Layer currentLayer)
{
DrawLine(lastPos, currentPos, currentLayer);
}

画线的实现:

    // 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;
}
}

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);
}
}
}
}

非常感谢您提供的任何帮助。

最佳答案

您可以锁定位图数据并使用指针手动设置值。它要快得多。尽管您将不得不使用不安全的代码。

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);

Bitmap bmp;
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = data.Stride;
unsafe
{
byte* ptr = (byte*)data.Scan0;
// 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);
ptr[(x * 3) + y * stride] = m_colour.B;
ptr[(x * 3) + y * stride + 1] = m_colour.G;
ptr[(x * 3) + y * stride + 2] = m_colour.R;
}
}
}
}
bmp.UnlockBits(data);
}

关于c# - SetPixel 太慢了。有没有更快的方法来绘制位图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7768711/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com