WPF RenderTargetBitmap 将 TextRenderMode 缩小到 GreyScale [英] WPF RenderTargetBitmap downscaling TextRenderMode to GreyScale

查看:23
本文介绍了WPF RenderTargetBitmap 将 TextRenderMode 缩小到 GreyScale的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

RenderTargetBitmap 移除将 RichtextBox 的 TextRenderingMode 降级为 GreyScale.所以捕获的 PNG 看起来质量很差,与 WPF 控件不匹配

RenderTargetBitmap removes downgrades a RichtextBox's TextRenderingMode to GreyScale. So a captured PNG looks poor quality and doesnt match the WPF control

如果我使用 WINDOWS ALT+PRINT SCREEN,则可以完美地捕获文本.

If I use WINDOWS ALT+PRINT SCREEN, the text is captured perfectly.

那么如何将文本控件呈现为与 ALT+PRINT SCREEN 相同的质量.

So how can I render the text control to the same quality as ALT+PRINT SCREEN.

任何建议将不胜感激

一切顺利

推荐答案

您可以使用与使用 Alt + Print Screen 截屏时使用的窗口相同的技术将窗口渲染到位图.这个想法是获取一个窗口句柄,然后使用 BitBlt 系统调用.

You can use the same technique to render your window into the bitmap as windows using when taking a screen shot with Alt + Print Screen. The idea is to get a window handle and then render it to a bitmap using BitBlt system call.

下面是一个示例(您需要在项目中引用 System.Drawing.dll 程序集才能使其工作):

Below is an example (you would need to reference the System.Drawing.dll assembly in your project to make it work):

public static void SaveToBitmapNative(Window window, FrameworkElement element, string fileName)
{
    WindowInteropHelper helper = new WindowInteropHelper(window);

    // detect the window client area position if rendering a child element
    double incX = 0, incY = 0;
    if (window != element)
    {
        System.Drawing.Point pos = new System.Drawing.Point(0, 0);
        ClientToScreen(helper.Handle, ref pos);
        incX = pos.X - (int)window.Left;
        incY = pos.Y - (int)window.Top;
    }

    // transform child position to window coordinates
    GeneralTransform transform = element.TransformToVisual(window);
    Point point = transform.Transform(new Point(0, 0));
    Rect rect = new Rect(point.X + incX, point.Y + incY, element.ActualWidth, element.ActualHeight);

    // render window into bitmap
    using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(
        (int)rect.Width, (int)rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
    {
        using (System.Drawing.Graphics memoryGraphics = System.Drawing.Graphics.FromImage(bitmap))
        {
            IntPtr dc = memoryGraphics.GetHdc();
            IntPtr windowDC = GetWindowDC(helper.Handle);

            BitBlt(dc, 0, 0, (int)rect.Width, (int)rect.Height,
                    windowDC, (int)rect.Left, (int)rect.Top, TernaryRasterOperations.SRCCOPY);

            memoryGraphics.ReleaseHdc(dc);
            ReleaseDC(helper.Handle, windowDC);
        }
        // save bitmap to file
        bitmap.Save(fileName);
    }
}

[DllImport("gdi32.dll")]
static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, TernaryRasterOperations rop);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr ptr);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("user32.dll")]
static extern bool ClientToScreen(IntPtr hWnd, ref System.Drawing.Point lpPoint);

public enum TernaryRasterOperations : uint
{
    SRCCOPY = 0x00CC0020,
    SRCPAINT = 0x00EE0086,
    SRCAND = 0x008800C6,
    SRCINVERT = 0x00660046,
    SRCERASE = 0x00440328,
    NOTSRCCOPY = 0x00330008,
    NOTSRCERASE = 0x001100A6,
    MERGECOPY = 0x00C000CA,
    MERGEPAINT = 0x00BB0226,
    PATCOPY = 0x00F00021,
    PATPAINT = 0x00FB0A09,
    PATINVERT = 0x005A0049,
    DSTINVERT = 0x00550009,
    BLACKNESS = 0x00000042,
    WHITENESS = 0x00FF0062
}

这是你如何称呼它

private void saveButton_Click(object sender, RoutedEventArgs e)
{
    // saves the entire window into the bitmap
    SaveToBitmapNative(this, this, "c:\\test0.png");
    // saves a child control (RichTextBox) into the bitmap
    SaveToBitmapNative(this, richTextBox, "c:\\test1.png"); 
}

注意:这不适用于通过 UpdateLayeredWindow 函数.

Note: this would not work for layered windows updated via UpdateLayeredWindow function.

希望对您有所帮助,问候

hope this helps, regards

这篇关于WPF RenderTargetBitmap 将 TextRenderMode 缩小到 GreyScale的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆