Необработанные растровые данные / строки сканирования (необработанные данные драйвера зеркала)? - PullRequest
5 голосов
/ 03 июля 2010

Я пишу решение для управления в реальном времени / удаленного рабочего стола, используя бесплатный драйвер зеркала DFMirage.Существует пример C # для интерфейса и управления драйвером зеркала здесь .Конечно, сначала нужно установить драйвер зеркала, здесь .Итак, концепция в том, что клиент (помощник) запрашивает обновление экрана, а сервер (жертва) отправляет его, используя необработанное кодирование пикселей.Концепция зеркального драйвера исключает необходимость дорогостоящего опроса изменений экрана, поскольку зеркальный драйвер уведомляется о всех операциях рисования экрана в режиме реального времени.Зеркальный драйвер получает местоположение и размер прямоугольника обновления и может просто запросить в памяти новые байты пикселя и отправить их.

Должно быть легко, за исключением того, что я не знаю, как выполнить эту часть, гдемы запрашиваем память для новых пикселей .Пример показывает, как запросить память, чтобы захватить пиксели всего экрана , используя что-то с необработанными растровыми данными, линиями сканирования и шагами, и все такое хорошее:

Bitmap result = new Bitmap(_bitmapWidth, _bitmapHeight, format);
Rectangle rect = new Rectangle(0, 0, _bitmapWidth, _bitmapHeight);
BitmapData bmpData = result.LockBits(rect, ImageLockMode.WriteOnly, format);

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

// Declare an array to hold the bytes of the bitmap.
int bytes = bmpData.Stride * _bitmapHeight;
var getChangesBuffer = (GetChangesBuffer)Marshal
    .PtrToStructure(_getChangesBuffer, typeof (GetChangesBuffer));
var data = new byte[bytes];
Marshal.Copy(getChangesBuffer.UserBuffer, data, 0, bytes);

// Copy the RGB values into the bitmap.
Marshal.Copy(data, 0, ptr, bytes);
result.UnlockBits(bmpData);
return result;

Это здоровои работает нормально.Полученный объект Bitmap теперь имеет пиксели всего экрана.Но если бы я хотел просто извлечь прямоугольник из данных пикселей вместо того, чтобы получать данные пикселей со всего экрана, как бы я мог это сделать?Я предполагаю, что это больше вопрос rawbitmap-scan-stepde, но я набрал все это, чтобы вы могли знать, откуда это исходит.Итак, есть ли понимание того, как получить только часть пиксельных данных вместо пиксельных данных всего экрана?

Обновление: найдено что-то интересное (только часть кода).

1 Ответ

0 голосов
/ 25 июня 2014

Вот функция для копирования прямоугольной области из некоторого буфера исходного изображения в Bitmap:

private static Bitmap ExtractImageRectangle(byte[] sourceBuffer, int sourceStride, PixelFormat sourcePixelFormat, Rectangle rectangle)
{
    Bitmap result = new Bitmap(rectangle.Width, rectangle.Height, sourcePixelFormat);
    BitmapData resultData = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, result.PixelFormat);

    int bytesPerPixel = GetBytesPerPixel(sourcePixelFormat); // Left as an exercise for the reader

    try
    {
        // Bounds checking omitted for brevity
        for (int rowIndex = 0; rowIndex < rectangle.Height; ++rowIndex)
        {
            // The address of the start of this row in the destination image
            IntPtr destinationLineStart = resultData.Scan0 + resultData.Stride * rowIndex;

            // The index at which the current row of our rectangle starts in the source image
            int sourceIndex = sourceStride * (rowIndex + rectangle.Top) + rectangle.Left * bytesPerPixel;

            // Copy the row from the source to the destination
            Marshal.Copy(sourceBuffer, sourceIndex, destinationLineStart, rectangle.Width * bytesPerPixel);
        }
    }
    finally
    {
        result.UnlockBits(resultData);
    }

    return result;
}

Вы можете использовать его так:

Rectangle roi = new Rectangle(100, 150, 200, 250);
Bitmap result = ExtractImageRectangle(getChangesBuffer.UserBuffer, getChangesBuffer.Stride, getChangesBuffer.PixelFormat, roi);

Предполагается, что GetChangesBuffer имеет свойства для шага и формата пикселей буфера исходного изображения. Скорее всего, нет, но у вас должны быть какие-то средства для определения шага и формата пикселей вашего входного изображения. В вашем примере вы предполагаете, что шаг входного изображения равен шагу вашего выходного изображения, что является хитрым предположением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...