Я работаю над оптимизацией программы, над которой я работаю, которая в настоящее время считывает байтовые данные с использованием битов блокировки, но записывает данные пикселей с помощью setPixel. Итак, как мне на самом деле изменить данные пикселей, которые я читаю? Если я попытаюсь установить pp, cp или np, метод не будет работать (поскольку он зацикливается и требует pp, cp и np для представления данных пикселей), поэтому я полностью запутался. Мне нужно записывать данные пикселей в byte [] и манипулировать ими, что ли?

Вот пример кода:

BitmapData data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height),
    ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

int scaledPercent = (int)(Math.Round(percentageInt * 255)) - 47;
Debug.WriteLine("percent " + scaledPercent);
unsafe
{
    Debug.WriteLine("Woah there, unsafe stuff");
    byte* prevLine = (byte*)data.Scan0;
    byte* currLine = prevLine + data.Stride;
    byte* nextLine = currLine + data.Stride;

    for (int y = 1; y < img.Height - 1; y++)
    {
        byte* pp = prevLine + 3;
        byte* cp = currLine + 3;
        byte* np = nextLine + 3;
        for (int x = 1; x < img.Width - 1; x++)
        {
            if (IsEdgeOptimized(pp, cp, np, scaledPercent))
            {
                //Debug.WriteLine("x " + x + "y " + y);
                img2.SetPixel(x, y, Color.Black);
            }
            else
            {
                img2.SetPixel(x, y, Color.White);
            }
            pp += 3; cp += 3; np += 3;
        }
        prevLine = currLine;
        currLine = nextLine;
        nextLine += data.Stride;
    }
}
img.UnlockBits(data);
pictureBox2.Image = img2;
3
vkoves 4 Сен 2013 в 21:31

1 ответ

Лучший ответ

SetPixel работает медленно по сравнению с получением необработанных битов в виде массива. Похоже, вы делаете какое-то обнаружение края (?). Пример для LockBits в MSDN (http://msdn.microsoft.com/en- us / library / 5ey6h79d.aspx) показывает, как получить необработанный массив и работать с ним, сохраняя результат обратно в исходное изображение.

Интересно то, что в этом примере байты копируются из указателя с помощью Marshal.copy:

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap. 
        int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
       byte[] rgbValues = new byte[bytes];

        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

Теперь у вас есть нужные вам значения в массиве rgbValues, и вы можете начать манипулировать ими.

5
Torgrim Brochmann 4 Сен 2013 в 21:45
Так что я могу внести соответствующие изменения в byte []. Это честно. Но как мне скопировать вывод в новое изображение?
 – 
vkoves
4 Сен 2013 в 21:55
1
Из той же статьи: '// Копируем значения RGB обратно в растровое изображение System.Runtime.InteropServices.Marshal.Copy (rgbValues, 0, ptr, bytes);'
 – 
Torgrim Brochmann
4 Сен 2013 в 22:06