Tôi đang sử dụng thư viện của bên thứ ba để hiển thị hình ảnh cho GDI DC và tôi cần đảm bảo rằng mọi văn bản được hiển thị mà không có bất kỳ hiệu ứng làm mịn/khử răng cưa nào để tôi có thể chuyển đổi hình ảnh thành một bảng màu được xác định trước với các màu được lập chỉ mục.Tắt tính năng chống răng cưa cho bối cảnh thiết bị GDI cụ thể
Thư viện của bên thứ ba mà tôi đang sử dụng để hiển thị không hỗ trợ điều này và chỉ hiển thị văn bản theo cài đặt cửa sổ hiện tại để hiển thị phông chữ. Họ cũng nói rằng không chắc họ sẽ thêm khả năng chuyển đổi chống răng cưa bất kỳ lúc nào.
Công việc tốt nhất xung quanh tôi đã tìm thấy cho đến nay là để gọi thư viện của bên thứ ba theo cách này (xử lý lỗi và các thiết lập kiểm tra trước ommitted cho ngắn gọn):
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);
Điều này rõ ràng có ảnh hưởng khủng khiếp trên hệ điều hành, các ứng dụng khác nhấp nháy từ cleartype được kích hoạt để vô hiệu hóa và trở lại mỗi khi tôi render hình ảnh.
Vì vậy, câu hỏi là, có ai biết cách tôi có thể thay đổi cài đặt hiển thị phông chữ cho một DC cụ thể không?
Thậm chí nếu tôi chỉ có thể thực hiện quy trình thay đổi hoặc chủ đề cụ thể thay vì ảnh hưởng đến toàn bộ hệ điều hành, đó sẽ là một bước tiến lớn! (Điều đó sẽ cung cấp cho tôi tùy chọn canh tác kết xuất này với một quy trình riêng biệt- kết quả được ghi vào đĩa sau khi hiển thị)
EDIT: Tôi muốn thêm rằng tôi không quan tâm nếu giải pháp phức tạp hơn chỉ là một vài cuộc gọi API. Tôi thậm chí muốn được hạnh phúc với một giải pháp có liên quan đến hooking hệ thống dlls nếu nó chỉ là về một ngày làm việc.
CHỈNH SỬA: Thông tin cơ bản Thư viện của bên thứ ba hiển thị bằng bảng màu khoảng 70 màu. Sau khi hình ảnh (mà thực sự là một lát bản đồ) được trả về DC, tôi chuyển đổi mỗi điểm ảnh từ màu 32 bit trở lại chỉ mục bảng màu của nó và lưu kết quả dưới dạng hình ảnh màu xám 8bpp. Điều này được tải lên thẻ video dưới dạng kết cấu. Trong khi dựng hình, tôi áp dụng lại bảng màu (cũng được lưu trữ dưới dạng kết cấu) với trình đổ bóng pixel thực thi trên thẻ video. Điều này cho phép tôi chuyển đổi và mờ dần giữa các bảng màu khác nhau ngay lập tức thay vì cần phải tạo lại tất cả các ô được yêu cầu. Phải mất từ 10-60 giây để tạo và tải lên tất cả các ô xếp để có cái nhìn tiêu biểu của thế giới.
EDIT: Đổi tên GraphicsDevice thành Graphics Lớp GraphicsDevice trong phiên bản trước của câu hỏi này thực sự là System.Drawing.Graphics. Tôi đã đổi tên nó (sử dụng GraphicsDevice = ...) bởi vì mã được đề cập nằm trong vùng tên MyCompany.Graphics và trình biên dịch không thể giải quyết nó đúng cách.
EDIT: Thành công! Tôi thậm chí còn quản lý chức năng PatchIat
dưới đây để C# với sự trợ giúp của Marshal.GetFunctionPointerForDelegate
. Nhóm interop .NET thực sự đã làm một công việc tuyệt vời! Bây giờ tôi đang sử dụng cú pháp sau, nơi Patch
là một phương pháp mở rộng trên System.Diagnostics.ProcessModule
:
module.Patch(
"Gdi32.dll",
"CreateFontIndirectA",
(CreateFontIndirectA original) => font =>
{
font->lfQuality = NONANTIALIASED_QUALITY;
return original(font);
});
private unsafe delegate IntPtr CreateFontIndirectA(LOGFONTA* lplf);
private const int NONANTIALIASED_QUALITY = 3;
[StructLayout(LayoutKind.Sequential)]
private struct LOGFONTA
{
public int lfHeight;
public int lfWidth;
public int lfEscapement;
public int lfOrientation;
public int lfWeight;
public byte lfItalic;
public byte lfUnderline;
public byte lfStrikeOut;
public byte lfCharSet;
public byte lfOutPrecision;
public byte lfClipPrecision;
public byte lfQuality;
public byte lfPitchAndFamily;
public unsafe fixed sbyte lfFaceName [32];
}
nếu mã này giải quyết được sự cố, có thể bạn nên đánh dấu câu trả lời của riêng bạn là câu trả lời được chấp nhận. –
@Justin, vâng điểm tốt. Như bạn có thể thấy từ những ngày tháng, tôi đã không đặt mã C# cho đến một năm sau đó, vì vậy tôi đã không nghĩ rằng để làm điều đó vào thời điểm đó. Tôi hy vọng @Chris Becke không mất đại diện cho câu trả lời đang được giao lại, tôi sẽ không bao giờ giải quyết vấn đề này nếu không có sự giúp đỡ của anh ấy. –
Làm tốt lắm! Lưu ý rằng điều này cũng hoạt động trên nền tảng x64 nhưng bạn cần sửa đổi cấu trúc ImageOptionalHeader một chút khi trường _BaseOfData_ không có trong IMAGE_OPTIONAL_HEADER64. – Poustic