Home

Bitmap dumped in result window should not scale with high DPI

edited July 2021

Let's say this code:

GetScreenBitmap().Dump();

Bitmap GetScreenBitmap()
{
    Rectangle b = Screen.GetBounds(Point.Empty);
    Bitmap bmp = new Bitmap(b.Width, b.Height);
    using Graphics g = Graphics.FromImage(bmp);
    g.CopyFromScreen(new Point(b.Left, b.Top), Point.Empty, b.Size);
    return bmp;
}

The dumped result image is actually much much bigger than the screen size, especially in high DPI screen. (>150%)

I believe there should be something we can do to make it better.

Comments

  • @JoeAlbahari Please take a look on this, this make dumped pictures much larger than expected and leading to misunderstand when debugging.

  • Because results are rendered in HTML, this is up to the browser, and it's standard behavior for pixels to be scaled with the DPI (at least with the Chromium engine). While it's counterproductive in the case of dumping a screen capture, it's desirable other contexts: for instance, a query that dumps a chart bitmap will give a similar output regardless of the DPI of the computer running the query.

    It would be nice to have an option to control the size of the image when dumping it, although I suspect it can never give perfect results in the case of a screen dump - at least with a browser rendering the results. The best would be to estimate how much the browser will expand the image and adjust it the other way. Of course, this could change easily with the zoom factor.

  • edited August 2021

    When rendering pictures, use physical pixel instead of scaled with DPI setting should be the perfect solution. But if we can't reach that, I think we should at least try scale down with scaled up DPI value, although it might not accurate and definitely blurry, but at lease size is the same, which solves one of the problems.

  • When rendering pictures, use physical pixel instead of scaled with DPI setting

    Do you know how to do that? I didn't think it was possible in HTML 5.

  • After look around in all kinds of forums, looks like it might not possible to use physical pixels in HTML5:
    https://discourse.wicg.io/t/display-an-image-at-device-s-physical-resolution/1150

    The another possible ways:

    • Using srcset attribute instead of src attribute: <img srcset="... 1.5x" />
    • Using transform = scale(1/window.devicePixelRatio)

    Either way will lead to blurry, but since it's already blurry, so I think it only make thing a little better, no more bad.

  • edited August 2021

    Looks like the srcset attribute in img tag is promising(no/not much noticable blurry):

  • @JoeAlbahari
    I confirmed using srcset attribute with img tag will be scaled correctly, I suggesting using srcset with correct DPI scale factor by default in LINQPad.

    For those who using multiple monitor, I suggesting just keep using the primary one, since LINQPad Per-Monitor-DPIAware is also absent :)

  • Just wrote a small piece of code snippet, all images scaling looks good when injecting to code before program runs:

    CorrectImageScale();
    
    for (int i = 0; i < 3; ++i)
    {
        Clipboard.GetImage().Dump();
        Thread.Sleep(500);
    }
    
    void CorrectImageScale()
    {
        Util.InvokeScript(needReturnValue: false, "eval", @$"
            if (window.imgInterval) clearInterval(window.imgInterval);
    
            window.imgInterval = setInterval(() => {{
                document.querySelectorAll('img').forEach(v => v.srcset = v.src + ' {GetScaleFactor()}x'); 
            }}, 500);
            ");
    
        decimal GetScaleFactor()
        {
            using Graphics g = Graphics.FromHwnd(IntPtr.Zero);
            return (decimal)g.DpiX / 96;
        }
    }
    

    Running result:

    Without the code snippets:

  • Thanks for the code - I'll look into how this can be incorporated and get something out hopefully this week.

  • Try the latest beta. You can now call DumpUnscaled() on images. This is a shortcut for calling Dump() with Util.ScaleMode.Unscaled. You can also specify a width and/or height (in browser pixels) as follows:

    myBitmap.Dump (Util.ScaleMode.ResizeTo (100, 100));
    

    Util.Image has also been updated to support Util.ScaleMode.

  • Oh, looks cool, confirmed Util.ScaleMode.Unscaled works for me, can it also provide a system level options for Bitmap dumped into result window? like:

Sign In or Register to comment.