本文介绍了的setPixel太慢。有没有提请位图一个更快的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的工作在一个小的画图程序。我使用位图来的setPixel做线的图。当画笔的大小变大,如25像素对面有一个明显的性能下降。我想知道如果有提请位图一个更快的方法。这里是一个位项目的背景

I have a small paint program that I am working on. I am using SetPixel on a bitmap to do that drawing of lines. When the brush size gets large, like 25 pixels across there is a noticeable performance drop. I am wondering if there is a faster way to draw to a bitmap. Here is a bit of the background of the project:


  • 我使用位图,这样我可以利用层,就像在Photoshop或GIMP。

  • 线被手工画出的,因为这将最终使用的图形输入板pressure以改变线在其长度的大小。

  • 的行最终应防aliaced /沿边缘平滑。

我会包括我的画code以防万一正是这一点是缓慢的,而不是设定像素位。

I'll include my drawing code just in case it is this that is slow and not the Set-Pixel bit.

这是在绘画发生在窗口:

This is in the windows where the painting happens:

    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的执行情况:


Implementation of MouseMove:

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


DrawLine的实施情况:


Implementation of 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;
        }
    }


PaintPoint的执行情况:


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

非常感谢任何帮助,您可以提供。

Thanks a lot for any help you can provide.

推荐答案

您可以锁定位图数据,并使用指针手动设置值。它的速度更快。虽然你将不得不使用不安全的code。

You can lock the bitmap data and use pointers to manually set the values. It's much faster. Though you'll have to use unsafe code.

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

这篇关于的setPixel太慢。有没有提请位图一个更快的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 14:28