简体   繁体   English

GDI+ 文本绘图不一致

[英]GDI+ Text Drawing Inconsistency

I have a program that generates ASCII art from input image.我有一个从输入图像生成 ASCII 艺术的程序。 The generated ASCII art is printed nicely in console.生成的 ASCII 艺术在控制台中打印得很好。 I have a function that also generates a PNG image with ASCII art using GDI+ .我有一个 function,它还使用GDI+生成带有 ASCII 艺术的PNG图像。 On my laptop, the generated image looks amazing and there is no problem.在我的笔记本电脑上,生成的图像看起来很棒,没有问题。

However using that SAME code on my other computer the generated image is skewed and doesn't look any good and i have no idea why.然而,在我的另一台计算机上使用相同的代码生成的图像是倾斜的,看起来不太好,我不知道为什么。

Note: For majority of my program i am using GDI+ , but for generating the image from my ASCII art i have to use GDI because i have to use raster font "Terminal" (which is available on any Windows machine), and GDI+ doesn't work with that font.注意:对于我的大部分程序,我使用的是GDI+ ,但是为了从我的 ASCII 艺术中生成图像,我必须使用GDI ,因为我必须使用光栅字体“终端”(可在任何 Windows 机器上使用),而 GDI+ 不无法使用该字体。 I have a slight clue that hfont is somehow creating an issue because if passed 8x8px font the image looks almost fine.我有一点线索, hfont不知何故造成了一个问题,因为如果通过 8x8px 字体,图像看起来几乎没问题。

The code of the function is: function 的代码是:

VOID ASCIIFied::generate_image(VOID)
{
    if (this->decoded_art == nullptr)
    {
        cerr << "Failed to produce image from art because it's accessing nullptr reference maybe due to failed art generation or art isn't decoded yet.\nTerminating the program." << endl;
        exit(EXIT_FAILURE);
    }

    // In pixels, each letter is 8x12px + some breathing space (char_height = vertical amount of characters in art, chars_per_line = same but on horizontal axis)
    INT image_width  = this->chars_per_line * 8 + 100;
    INT image_height = this->char_height * 12 + 200;

    // Generate bitmap to draw to
    Bitmap art_output(image_width, image_height);
    Graphics g(&art_output);

    // Sets background to black
    Color color(Color::Black);
    g.Clear(color);

    // Creating proper font
    HFONT hfont = CreateFont(-8, -12, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, L"Terminal");

    // Text bounding rectangle
    RECT rc = { 50, 50, image_width,  image_height};

    HDC hdc = g.GetHDC();

    // Setting text background and foreground color to console colors along side with font
    SetBkColor(hdc, RGB(0, 0, 0));
    SetTextColor(hdc, RGB(210, 210, 210));

    // Apply font
    SelectObject(hdc, hfont);

    DrawTextA(hdc, this->decoded_art, -1, &rc, DT_LEFT | DT_TOP | DT_WORDBREAK);

    g.ReleaseHDC(hdc);
    DeleteObject(hfont);

    WCHAR path[MAX_PATH];

    // Get Desktop path
    if (SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, path) != S_OK)
    {
        cerr << "DESKTOP path not found!\n";
        exit(EXIT_FAILURE);
    }

    SYSTEMTIME time_s;
    GetSystemTime(&time_s);

    wstring day    = to_wstring(time_s.wDay);
    wstring month  = to_wstring(time_s.wMonth);
    wstring year   = to_wstring(time_s.wYear);
    wstring hour   = to_wstring(time_s.wHour);
    wstring minute = to_wstring(time_s.wMinute);
    wstring second = to_wstring(time_s.wSecond);

    wstring image_path(path);
    image_path += L"\\ascii_art_" + day + L"-" + month + L"-" + year + L"-" + hour + L"-" + minute + L"-" + second + L".png";

    CLSID encId = { 0x557cf406, 0x1a04, 0x11d3,{ 0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e } };
    art_output.Save(image_path.c_str(), &encId);

    cout << "Image saved to your desktop." << endl;
}

Example of a good and bad image generation respectively ->分别生成好图像和坏图像的示例 ->

Good好的

Bad坏的

The solution was quite simple and what was causing the problem was so easily overlooked.解决方案非常简单,导致问题的原因很容易被忽视。

On MSDN page for CreateFontW() function the first argument is font height , and then the second argument is font width .CreateFontW() function 的 MSDN 页面上,第一个参数是font height ,然后第二个参数是font width

From the provided code in my question, the bitmap width and height is calculated correctly for desired font (8x12px raster font Terminal)根据我问题中提供的代码,正确计算了所需字体的 bitmap 宽度和高度(8x12px 光栅字体终端)

// In pixels, each letter is 8x12px + some breathing space (char_height = vertical amount of characters in art, chars_per_line = same but on vertical axis)
INT image_width  = this->chars_per_line * 8 + 100;
INT image_height = this->char_height * 12 + 200;

But when actual font is created in the code, the order of arguments for font width and height is reversed when provided therefore the font mapper searches for wrong sized font which consequently won't fit when drawn in the created bitmap. IE:但是,当在代码中创建实际字体时,提供的字体宽度和高度 arguments 的顺序是相反的,因此字体映射器搜索错误大小的字体,因此在创建的 bitmap 中绘制时不适合。IE:

 HFONT hfont = CreateFont(-8, -12, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, L"Terminal");

The solution was to switch -8 and -12 in the function call.解决方案是在 function 调用中切换 -8 和 -12。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM