2010-07-03 5 views
5

Je suis en train de coder une solution de contrôle à distance/bureau à distance en utilisant le pilote miroir libre de DFMirage. Il existe un exemple C# sur la façon d'interfacer et de contrôler le pilote miroir here. Vous auriez besoin du pilote miroir installé en premier, bien sûr, here. Ainsi, le concept est, le client (assistant) demande une mise à jour de l'écran, et le serveur (victime) en envoie un, en utilisant un codage brut des pixels. Le concept d'un pilote miroir élimine le besoin d'interroger de manière coûteuse les modifications d'écran, car un pilote miroir est averti de toutes les opérations de dessin d'écran en temps réel. Le pilote miroir reçoit l'emplacement et la taille du rectangle de mise à jour et peut simplement interroger la mémoire pour les nouveaux octets de pixels et les envoyer.Données bitmap brutes/lignes de balayage (données brutes du pilote miroir)?

Devrait être facile, sauf que je ne sais pas comment faire cette partie où nous interroger la mémoire pour les nouveaux octets de pixel. L'exemple montre comment interroger la mémoire pour saisir les pixels de l'écran entier en utilisant quelque chose avec des données bitmap brutes et les lignes de balayage et la foulée et toutes ces bonnes choses:

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; 

C'est grand et fonctionne très bien. L'objet Bitmap résultant a maintenant les pixels de l'écran entier. Mais si je voulais simplement extraire un rectangle de données de pixels au lieu d'obtenir les données de pixels de l'ensemble de l'écran, comment pourrais-je faire cela? Je suppose que c'est plus une question rawbitmap-scan-stride, mais j'ai tapé tout cela pour que vous sachiez d'où cela vient. Donc, un aperçu sur la façon d'obtenir juste une partie des données de pixels au lieu de l'ensemble des données de pixel de l'écran?

Mise à jour: trouvé quelque chose interesting (portion de code uniquement).

Répondre

0

est ici une fonction pour copier une zone rectangulaire de quelque tampon d'image source à un 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; 
} 

Vous pouvez alors l'utiliser comme ceci:

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

Cela suppose que GetChangesBuffer a des propriétés pour la foulée et le format de pixel du tampon d'image source. Ce n'est probablement pas le cas, mais vous devriez avoir un moyen de déterminer le format de la foulée et des pixels de votre image d'entrée. Dans votre exemple, vous supposez que la foulée de l'image d'entrée est égale à la foulée de votre image de sortie, ce qui est une hypothèse difficile.

Questions connexes