2010-07-13 10 views
6

Sto utilizzando la funzione win32 PrintWindow per acquisire una schermata su un oggetto BitMap.Come acquisire una parte di uno schermo

Se voglio solo catturare una regione della finestra, come posso ritagliare l'immagine in memoria?

Ecco il codice che sto usando per catturare l'intera finestra:

[System.Runtime.InteropServices.DllImport(strUSER32DLL, CharSet = CharSet.Auto, SetLastError = true)] 
public static extern int PrintWindow(IntPtr hWnd, IntPtr hBltDC, uint iFlags); 

public enum enPrintWindowFlags : uint 
{ 
    /// <summary> 
    /// 
    /// </summary> 
    PW_ALL = 0x00000000, 
    /// <summary> 
    /// Only the client area of the window is copied. By default, the entire window is copied. 
    /// </summary> 
    PW_CLIENTONLY = 0x00000001 
} 

public System.Drawing.Bitmap CaptureWindow(IntPtr hWnd, enPrintWindowFlags eFlags) 
{ 
    System.Drawing.Rectangle rctForm = System.Drawing.Rectangle.Empty; 

    using(System.Drawing.Graphics grfx = System.Drawing.Graphics.FromHdc(GetWindowDC(hWnd))) 
    { 
     rctForm = System.Drawing.Rectangle.Round(grfx.VisibleClipBounds); 
    } 

    System.Drawing.Bitmap pImage = new System.Drawing.Bitmap(rctForm.Width, rctForm.Height); 
    System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(pImage); 

    IntPtr hDC = graphics.GetHdc();   
    //paint control onto graphics using provided options   
    try 
    {    
     PrintWindow(hWnd, hDC, (uint)eFlags);  
    } 
    finally 
    {    
     graphics.ReleaseHdc(hDC);   
    }  
    return pImage; 
} 

risposta

3

Si potrebbe semplicemente afferrare l'intero schermo e quindi passare l'immagine in una funzione di ritaglio che seleziona una regione dell'immagine totale. Dai un'occhiata al metodo Bitmap.Clone(). per esempio.

public Bitmap CropBitmap(Bitmap bitmap, int cropX, int cropY, int cropWidth, int cropHeight) 
{ 
Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight); 
Bitmap cropped = bitmap.Clone(rect, bitmap.PixelFormat); 
return cropped; 
} 

nota, ho tirato giù da questo this blog

+0

Questo è quello che stavo pensando ... potrebbe essere possibile afferrare solo quella parte, ma questo è molto più semplice. – Adam

0

risparmiare qualche difficoltà e prendere la fonte a Cropper.

3

Ecco il codice completo per catturare lo schermo e creare un'immagine ritagliata di 100 pixel quadrati. Il codice è preso da un evento Click del pulsante. Usa quello di cui hai bisogno.

Bitmap screenShot = null; 
     Bitmap croppedImage; 
     Graphics screen; 

     if(saveFileDialog.ShowDialog() == DialogResult.OK) 
     { 
      this.Hide(); 
      screenShot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, 
            Screen.PrimaryScreen.Bounds.Height, 
            PixelFormat.Format32bppArgb); 
      screen = Graphics.FromImage(screenShot); 
      screen.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, 
            Screen.PrimaryScreen.Bounds.Y, 
            0, 
            0, 
            Screen.PrimaryScreen.Bounds.Size, 
            CopyPixelOperation.SourceCopy); 
      screenShot.Save(saveFileDialog.FileName, ImageFormat.Png); 
      this.Show(); 
     } 

     //crop image 
     if(screenShot != null) 
     { 
      if(saveFileDialog.ShowDialog() == DialogResult.OK) 
      { 
       int x = 100; 
       int y = 100; 
       int xWidth = 100; 
       int yHeight = 100; 
       Rectangle rect = new Rectangle(x, y, xWidth, yHeight); 
       croppedImage = screenShot.Clone(rect, PixelFormat.Format32bppArgb); 
       if (croppedImage != null) 
       { 
        croppedImage.Save(saveFileDialog.FileName, ImageFormat.Png); 
       }  
      }     
     }