具有不同显示缩放问题的 C# WPF 显示屏幕截图
C# WPF Display screenshot with different display scaling issue
我有一个应用程序可以截取每个可用显示的屏幕截图,并根据图像将其放置在边框(图像 - 文本块)中。当我的所有屏幕在 Windows 显示设置中将显示缩放设置为 100% 时,一切正常,但是如果 1 个屏幕设置为不同的缩放设置,它看起来很奇怪。
以下所有缩放比例均为 100% - 完美 -
以下主屏幕缩放比例为 150%,其他 2 个屏幕缩放比例为 100%
以下是所有屏幕都为 150%
很明显,当 1 个屏幕作为不同的缩放设置时,问题就出现了。
我该如何纠正?
这是我的代码:
public ScreensListDesignModel()
{
Items = new List<ScreensItemViewModel>();
try
{
int i = 1;
foreach (Screen screen in Screen.AllScreens)
{
#region Grab the screenshot from each display
// Define bitmap
Bitmap screenshot = new Bitmap(screen.Bounds.Width,
screen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// Define graphics object
Graphics memoryGraphics = Graphics.FromImage(screenshot);
memoryGraphics.CopyFromScreen(screen.Bounds.X,
screen.Bounds.Y, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy);
#endregion
#region Get screens info and display the screenshots in each imagebox
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
string SN = "Screen " + i;
if (screen.Primary)
SN = "Main Screen";
Items.Add(new ScreensItemViewModel
{
Screenshot = CreateBitmapSourceFromGdiBitmap(screenshot),
ScreenName = SN,
});
});
i++;
screenshot.Dispose();
#endregion
}
}
catch (System.ComponentModel.Win32Exception) { } // action?
catch (System.NullReferenceException) { } // not sure
catch (System.Threading.Tasks.TaskCanceledException) { throw; };
}
和
private static BitmapSource CreateBitmapSourceFromGdiBitmap(Bitmap bitmap)
{
// Transform the image for CaptureScreen method
if (bitmap == null)
throw new ArgumentNullException("bitmap");
var rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
var bitmapData = bitmap.LockBits(
rect,
ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
try
{
var size = (rect.Width * rect.Height) * 4;
return BitmapSource.Create(
bitmap.Width,
bitmap.Height,
bitmap.HorizontalResolution,
bitmap.VerticalResolution,
PixelFormats.Bgra32,
null,
bitmapData.Scan0,
size,
bitmapData.Stride);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
}
其实修复很简单,只需要在里面添加一个app.manifest文件:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
我有一个应用程序可以截取每个可用显示的屏幕截图,并根据图像将其放置在边框(图像 - 文本块)中。当我的所有屏幕在 Windows 显示设置中将显示缩放设置为 100% 时,一切正常,但是如果 1 个屏幕设置为不同的缩放设置,它看起来很奇怪。
以下所有缩放比例均为 100% - 完美 -
以下主屏幕缩放比例为 150%,其他 2 个屏幕缩放比例为 100%
以下是所有屏幕都为 150%
很明显,当 1 个屏幕作为不同的缩放设置时,问题就出现了。 我该如何纠正?
这是我的代码:
public ScreensListDesignModel()
{
Items = new List<ScreensItemViewModel>();
try
{
int i = 1;
foreach (Screen screen in Screen.AllScreens)
{
#region Grab the screenshot from each display
// Define bitmap
Bitmap screenshot = new Bitmap(screen.Bounds.Width,
screen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// Define graphics object
Graphics memoryGraphics = Graphics.FromImage(screenshot);
memoryGraphics.CopyFromScreen(screen.Bounds.X,
screen.Bounds.Y, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy);
#endregion
#region Get screens info and display the screenshots in each imagebox
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
string SN = "Screen " + i;
if (screen.Primary)
SN = "Main Screen";
Items.Add(new ScreensItemViewModel
{
Screenshot = CreateBitmapSourceFromGdiBitmap(screenshot),
ScreenName = SN,
});
});
i++;
screenshot.Dispose();
#endregion
}
}
catch (System.ComponentModel.Win32Exception) { } // action?
catch (System.NullReferenceException) { } // not sure
catch (System.Threading.Tasks.TaskCanceledException) { throw; };
}
和
private static BitmapSource CreateBitmapSourceFromGdiBitmap(Bitmap bitmap)
{
// Transform the image for CaptureScreen method
if (bitmap == null)
throw new ArgumentNullException("bitmap");
var rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
var bitmapData = bitmap.LockBits(
rect,
ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
try
{
var size = (rect.Width * rect.Height) * 4;
return BitmapSource.Create(
bitmap.Width,
bitmap.Height,
bitmap.HorizontalResolution,
bitmap.VerticalResolution,
PixelFormats.Bgra32,
null,
bitmapData.Scan0,
size,
bitmapData.Stride);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
}
其实修复很简单,只需要在里面添加一个app.manifest文件:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>