2010-07-03 154 views
5

我正在使用DFMirage的免費鏡像驅動程序編寫實時控制/遠程桌面解決方案。有關於如何連接和控制鏡像驅動程序的C#示例here。您需要先安裝鏡像驅動程序,當然,需要安裝here。所以,概念是,客戶端(幫助者)請求屏幕更新,服務器(受害者)使用原始像素編碼發送一個屏幕更新。鏡像驅動程序的概念消除了花費昂貴的輪詢屏幕更改的需要,因爲鏡像驅動程序會實時通知所有屏幕繪圖操作。鏡像驅動程序接收更新矩形的位置和大小,並可以簡單地查詢內存中的新像素字節併發送它們。原始位圖數據/掃描行(鏡像驅動程序原始數據)?

應該很容易,除了我不知道該怎麼做,我們查詢內存的新像素字節。該示例展示瞭如何查詢內存搶使用與原始位圖數據和掃描線和步幅,所有的好東西東西整個屏幕像素:

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-stride問題,但我輸入了所有這些,以便您可以知道這是從哪裏來的。那麼,有關如何獲取像素數據的一部分而不是整個屏幕的像素數據的任何見解?

更新:發現東西interesting(僅限代碼部分)。

回答

0

這裏是一個函數的矩形區域,從一些源圖像緩衝區拷貝到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有屬性源圖像緩衝區的步幅和像素格式。它最有可能沒有,但你應該有一些手段來確定你的輸入圖像的步幅和像素格式。在你的例子中,你假設輸入圖像的步幅等於輸出圖像的步幅,這是一個棘手的假設。