@Preston073

Как влияют указатели на быстроту работу метода считывания цвета с битмапки?

Подскажите пожалуйста, разобраться: почему этот метод для считывания цвета с битмапки
public unsafe static byte[, ,] BitmapToByteRgb(Bitmap bmp)
{
    int width = bmp.Width,
        height = bmp.Height;
    byte[, ,] res = new byte[3, height, width];
    BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
        PixelFormat.Format24bppRgb);
    try
    {
        byte* curpos;
        for (int h = 0; h < height; h++)
        {
            curpos = ((byte*)bd.Scan0) + h * bd.Stride;
            for (int w = 0; w < width; w++)
            {
                res[2, h, w] = *(curpos++);
                res[1, h, w] = *(curpos++);
                res[0, h, w] = *(curpos++);
            }
        }
    }
    finally
    {
        bmp.UnlockBits(bd);
    }
    return res;
}

работает намного быстрее этого
public static byte[, ,] BitmapToByteRgbNaive(Bitmap bmp)
{
    int width = bmp.Width,
        height = bmp.Height;
    byte[, ,] res = new byte[3, height, width];
    for (int y = 0; y < height; ++y)
    {
        for (int x = 0; x < width; ++x)
        {
            Color color = bmp.GetPixel(x, y);
            res[0, y, x] = color.R;
            res[1, y, x] = color.G;
            res[2, y, x] = color.B;
        }
    }
    return res;
}

На хабре сказано, что дело в указателях . А как конкретно они влияют?
  • Вопрос задан
  • 282 просмотра
Пригласить эксперта
Ответы на вопрос 1
Nipheris
@Nipheris Куратор тега C#
Так влияют, что вы пишете/читаете напрямую в ту память, которая будет потом использовать Bitmap-ом для отрисовки/сохранения и всего прочего. В частности, у вас нет вызовов GetPixel/SetPixel, которые ОЧЕНЬ МЕДЛЕННЫЕ для данной задачи. У вас цикл по двум измерениям картинки, т.е. вызовов GetPixel будет width * height штук. Поверьте, это много и тяжело. Адресная арифметика, а именно
curpos = ((byte*)bd.Scan0) + h * bd.Stride;
намного легче. Собственно, возможность ее применения обеспечивается блокировкой реальных данных битмапа методом LockBits. Под блокировкой здесь понимается пометка для кода CLR, в частности для GC, что этот участок памяти трогать нельзя (перемещать, например), пока вы эту пометку не снимете.
Собственно говоря, более-менее быстрая работа с Bitmap возможна только через BitmapData, так как используя Get/SetPixel вы не дождетесь конца работы вашего алгоритма.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы