相关疑难解决方法(0)

禁用特定GDI设备上下文的抗锯齿

我正在使用第三方库将图像渲染到GDI DC,我需要确保在没有任何平滑/抗锯齿的情况下渲染任何文本,以便我可以将图像转换为带有索引颜色的预定义调色板.

我用于渲染的第三方库不支持这个,只是根据字体渲染的当前窗口设置呈现文本.他们还表示他们不太可能在短时间内添加切换抗锯齿功能.

到目前为止,我发现的最好的工作是以这种方式调用第三方库(为简洁起见,省略了错误处理和先前的设置检查):

private static void SetFontSmoothing(bool enabled)
{
    int pv = 0;
    SystemParametersInfo(Spi.SetFontSmoothing, enabled ? 1 : 0, ref pv, Spif.None);
}

// snip
Graphics graphics = Graphics.FromImage(bitmap)
IntPtr deviceContext = graphics.GetHdc();

SetFontSmoothing(false);
thirdPartyComponent.Render(deviceContext);
SetFontSmoothing(true);
Run Code Online (Sandbox Code Playgroud)

这显然对操作系统产生了可怕的影响,每次我渲染图像时,其他应用程序都会从​​禁用的cleartype闪烁到禁用和返回.

所以问题是,有没有人知道如何改变特定DC的字体渲染设置?

即使我可以只进行更改过程或线程而不是影响整个操作系统,这将是向前迈出的一大步!(这样我就可以选择将这个渲染转换为一个单独的进程 - 无论如何都会在渲染后将结果写入磁盘)

编辑:我想补充一点,我不介意解决方案是否比一些API调用更复杂.我甚至会对一个解决方案感到满意,如果它只用了一天工作就会挂钩系统dll.

编辑:背景信息 第三方库使用约70种颜色的调色板渲染.在将图像(实际上是地图图块)渲染到DC之后,我将每个像素从其32位颜色转换回其调色板索引,并将结果存储为8bpp灰度图像.这将作为纹理上传到视频卡.在渲染过程中,我重新应用了调色板(也存储为纹理),并在视频卡上执行了像素着色器.这允许我立即在不同的调色板之间切换和淡入淡出,而不需要重新生成所有需要的切片.生成并上传所有瓷砖需要10-60秒才能获得典型的世界观.

编辑:将GraphicsDevice重命名为图形 此问题的先前版本中的GraphicsDevice类实际上是System.Drawing.Graphics.我重命名了它(使用GraphicsDevice = ...),因为有问题的代码在命名空间MyCompany.Graphics中,编译器无法正确解析它.

编辑:成功! 我甚至设法将PatchIat下面的函数移植到C#的帮助下Marshal.GetFunctionPointerForDelegate..NET互操作团队确实做得非常出色!我现在使用以下语法,其中Patch是一个扩展方法System.Diagnostics.ProcessModule:

module.Patch(
    "Gdi32.dll",
    "CreateFontIndirectA",
    (CreateFontIndirectA original) => font =>
    {
        font->lfQuality = NONANTIALIASED_QUALITY;
        return original(font);
    });

private unsafe delegate …
Run Code Online (Sandbox Code Playgroud)

c# hook winapi gdi cleartype

9
推荐指数
2
解决办法
4416
查看次数

标签 统计

c# ×1

cleartype ×1

gdi ×1

hook ×1

winapi ×1