Что управляет масштабированием DC? - PullRequest
0 голосов
/ 29 ноября 2018

Этот код получает различное масштабирование в зависимости от того, на каком компьютере я его запускаю.

        Metafile image;
        IntPtr dib;
        var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, 1, 1, out dib);
        try
        {
            image = new Metafile(memoryHdc, EmfType.EmfOnly);

            using (var g = Graphics.FromImage(image))
            {
                Render(g, html, left, top, maxWidth, cssData, stylesheetLoad, imageLoad);
            }
        }
        finally
        {
            Win32Utils.ReleaseMemoryHdc(memoryHdc, dib);
        }

В методе Render объект Metafile имеет PixelFormat DontCare и, следовательно, не имеет допустимых разрешений по вертикали или горизонтали..

Исходя из метода Render, он имеет значение Format32bppRgb, а PhysicalDimension.Width и PhysicalDimension.Height увеличились для размещения визуализированного изображения.

Как я могусделать масштабирование независимым от локальных настроек?

Вот реализация CreateMemoryHdc (я не писал, это из библиотеки OSS).

    public static IntPtr CreateMemoryHdc(IntPtr hdc, int width, int height, out IntPtr dib)
    {
        // Create a memory DC so we can work off-screen
        IntPtr memoryHdc = CreateCompatibleDC(hdc);
        SetBkMode(memoryHdc, 1);

        // Create a device-independent bitmap and select it into our DC
        var info = new BitMapInfo();
        info.biSize = Marshal.SizeOf(info);
        info.biWidth = width;
        info.biHeight = -height;
        info.biPlanes = 1;
        info.biBitCount = 32;
        info.biCompression = 0; // BI_RGB
        IntPtr ppvBits;
        dib = CreateDIBSection(hdc, ref info, 0, out ppvBits, IntPtr.Zero, 0);
        SelectObject(memoryHdc, dib);

        return memoryHdc;
    }

Как вы можетевидите, ширина, высота и битовая глубина, передаваемые конструктору DC, являются постоянными.Создание метафайла производит различные физические измерения.Сразу после выполнения этого

            image = new Metafile(memoryHdc, EmfType.EmfOnly);

метафайл имеет PhysicalDimension.Height (и ширину) 26,43 на моей рабочей станции и 31,25 на сервере, на котором я выполняю развертывание, поэтому разница в масштабировании уже очевидна и, следовательно, вероятноне является следствием чего-либо в рендеринге.

Это может быть актуально.BitMapInfo определено в библиотеке OSS и выглядит следующим образом:

internal struct BitMapInfo
{
    public int biSize;
    public int biWidth;
    public int biHeight;
    public short biPlanes;
    public short biBitCount;
    public int biCompression;
    public int biSizeImage;
    public int biXPelsPerMeter;
    public int biYPelsPerMeter;
    public int biClrUsed;
    public int biClrImportant;
    public byte bmiColors_rgbBlue;
    public byte bmiColors_rgbGreen;
    public byte bmiColors_rgbRed;
    public byte bmiColors_rgbReserved;
}

, поэтому, возможно, установка biXPelsPerMeter и biYPelsPerMeter поможет.Приведенный выше код не не устанавливает их и может разрешать значения платформы.

К сожалению, установка этих значений, похоже, не имеет значения.msdn говорит

biXPelsPerMeter

Горизонтальное разрешение в пикселях на метр целевого устройства для растрового изображения.Приложение может использовать это значение для выбора растрового изображения из группы ресурсов, которое наилучшим образом соответствует характеристикам текущего устройства.

Таким образом, эти настройки используются, когда загрузка растровое изображение из ресурса .Здесь ничего не поделаешь.

Все это выглядит уместно https://www.codeproject.com/articles/177394/%2fArticles%2f177394%2fWorking-with-Metafile-Images-in-NET

Может быть полезно знать, что этот код не запускается в приложении.Он отображает HTML как метафайл для печати и живет в веб-сервисе Web API.

Нет пользовательского интерфейса, поэтому я не уверен, как интерпретировать вопрос о том, поддерживает ли он DPI.Доказательства предполагают, что его DPI затронул , поэтому вопрос может быть уместным.

1 Ответ

0 голосов
/ 03 декабря 2018

GDI не масштабируется.Используйте GDI + для независимости устройства.Вы потеряете сглаживание, но большинство печатающих устройств в любом случае имеют высокое разрешение.

Есть ли у используемой библиотеки возможность использовать вместо нее GDI +?

(В моем случае да. Проблема решена.)

...