Search code examples
c#.netzoomingloupemagnify

Magnify a specific area of the screen


I am working on making a loupe tool using C#. Much like this one: http://colorsnapper.com I have searched all over Google for a way to zoom in on a predefined area of the screen, enough to view each individual pixel.

To be more specific, I want my mouse to become a magnifying glass on the screen that enhances each pixel the mouse hovers over. I need to figure out how to magnify that predefined area.

Does anyone know of a way I can do this, or any APIs that are available.

UPDATE I have found a Magnification API that Microsoft has provided: http://msdn.microsoft.com/en-us/library/windows/desktop/ms692402(v=vs.85).aspx However, this API is in C++. As I have gathered, C++ is what the Windows OS is written in, and to use this API I will need to use some sort of C# wrapper. This isn't a question, I just thought I would add to this post for other users.


Solution

  • You could capture the screen to a bitmap in memory:

    /// <summary>
    /// Saves a picture of the screen to a bitmap image.
    /// </summary>
    /// <returns>The saved bitmap.</returns>
    private Bitmap CaptureScreenShot()
    {
        // get the bounding area of the screen containing (0,0)
        // remember in a multidisplay environment you don't know which display holds this point
        Rectangle bounds = Screen.GetBounds(Point.Empty);
    
        // create the bitmap to copy the screen shot to
        Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
    
        // now copy the screen image to the graphics device from the bitmap
        using (Graphics gr = Graphics.FromImage(bitmap))
        {
               gr.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
        }
    
        return bitmap;
    }
    

    And then take a portion of the image perhaps a 50px by 50px rectangle centered at the mouse position:

    portionOf = bitmap.Clone(new Rectangle(pointer.X - 25, pointer.Y - 25, 50, 50), PixelFormat.Format32bppRgb);
    

    And display it in a 100px by 100px rectangle centered at the mouse position. That would give you a 2X zoom level. The larger the ratio of (displayed size)/(captured size) the more you zoom. Something along the lines of:

    [DllImport("User32.dll")]
    public static extern IntPtr GetDC(IntPtr hwnd);
    
    [DllImport("User32.dll")]
    public static extern void ReleaseDC(IntPtr hwnd, IntPtr dc);
    
    void OnPaint()
    {
        IntPtr desktopDC = GetDC(IntPtr.Zero); // Get the full screen DC
    
        Graphics g = Graphics.FromHdc(desktopDC); // Get the full screen GFX device
    
        g.DrawImage(portionOf, pointer.X - 50, pointer.Y - 50, 100, 100); // Render the image
    
        // Clean up
        g.Dispose();
        ReleaseDC(IntPtr.Zero, desktopDC);
    }