Nano Hash - криптовалюты, майнинг, программирование

почему мой шрифт TrueType размера 11 отличается от Windows?

А именно: блокнот открыт, шрифт выбран как Arial, размер 11, слова это просто тест тщательно введены, сделан снимок экрана:

оригинал

Вводится и запускается следующий код Python:

import ImageFont, ImageDraw, Image
im = Image.open("c:/textimg.png") #the above image

pilfont = ImageFont.truetype("arial.ttf", 11)

compimg = Image.new("RGB", im.size, (255, 255, 255))
draw = ImageDraw.Draw(compimg)

draw.text((0,0), "this is just a test", (0,0,0), font=pilfont)

compimg.save("c:/compimg.png")

Однако результат разочаровывает:

грустно

Он не только неправильного размера, но и слегка затемнен, в то время как рендеринг в блокноте четкий и не выходит за границы пикселей.

Как я могу заставить его отображать, как блокнот? У меня была точно такая же проблема с pygame, поэтому я думаю, что мне здесь не хватает фундаментального понимания TTF.

ОБНОВЛЕНИЕ: я снова попробовал это с pygame. Он делает то же самое. У него есть возможность отключить сглаживание, но похоже, что он просто отсекает любые пиксели, которые были бы сглажены, на основе некоторого порога. Самое близкое приближение, которое я получил, это размер 15. Код был таким:

pygfont = pygame.font.Font(r"c:\windows\fonts\arial.ttf", 15)
surf = pygfont.render("this is just a test", False, (0,0,0), (255,255,255))
pygame.image.save(surf, r"c:\pygameimg.png")

и результат (оригинал блокнота сверху для сравнения):

http://tinypic.com/images/404.gif

Гах, почему я не могу сразу предложить награду?

ОБНОВЛЕНИЕ: здесь сравниваются все методы:

АИФЕОИФЕФ

PIL 15, затем блокнот 11, затем сглаживание pygame 15 выключено, затем сглаживание pygame 15 включено.

PIL 15 на самом деле имеет правильные пропорции, он просто сглажен. Итак: почему 15 против 11? как сделать так же, как в винде? (и что делает pygame?)


  • Изображение здесь исчезло, вы можете обновить ссылку? 23.01.2015

Ответы:


1

Рендеринг шрифтов — сложный и тонкий процесс, который реализовывался несколько раз. В вашем случае PIL и Windows выглядят по-разному, потому что они используют совершенно разные механизмы рендеринга шрифтов. Windows использует свой встроенный рендеринг, а PIL использует Freetype, с которым он был скомпилирован.

Я не знаю, как каждая среда интерпретирует свой параметр «размер», но даже если вы интерпретируете их одинаково, рендеринг будет просто другим. Чтобы получить те же пиксели, что и у Блокнота, нужно запустить Блокнот и захватить экран.

Возможно, если вы объясните подробнее, почему вам нужен тот же рендеринг, что и в «Блокноте», у нас будут творческие решения вашей проблемы.

21.04.2011
  • есть ли способ рендеринга с использованием метода Windows из Python? причина, по которой я хочу отображать то же, что и блокнот, заключается в том, что я хочу автоматически определять, какой шрифт использует программа. я могу только надеяться на это, если они используют простой рендеринг без сглаживания, и мне удалось сопоставить их вручную, используя рисование/блокнот и сравнивая его со скриншотами, так что это то, что я пытаюсь имитировать. 22.04.2011
  • на самом деле многие программы используют флэш, поэтому, если я смогу найти способ заставить флэш отображать мои шрифты, это было бы мило.. 22.04.2011
  • также спасибо за указание на алгоритм PIL. я узнаю больше о рендеринге шрифтов, чем когда-либо хотел знать. 22.04.2011

  • 2

    Я думаю, что «размер» Блокнота - это размер точек, а «размер» ImageFont.truetype () - пиксели.

    21.04.2011
  • и.. что я могу с этим поделать? я хочу сделать то же самое, что и блокнот, в частности, чтобы избавиться от любого сглаживания, которое может происходить 21.04.2011
  • я тоже не уверен, что это правда. высота «h» в блокноте равна 11, тогда как высота «h» равна 7 или 8 с PIL. 22.04.2011

  • 3

    Размеры выходят разные, потому что они указаны по-разному. Чтобы преобразовать точки в пиксели, используйте формулу: pixels = points * 96 / 72, где 96 — это значение DPI, настроенное в Windows (а не фактическое значение DPI монитора). В вашем случае 11*96/72 = 14,6666, что округляется до 15.

    Что касается идентичности текста попиксельно, это будет невозможно с помощью предоставленных инструментов - Нед прав. Если это абсолютно необходимо, вам нужно будет использовать Windows API, чтобы отобразить этот текст для вас и скопировать его в изображение. Не простой процесс.

    21.04.2011
  • хм, не могли бы вы подсказать, с чего я могу начать использовать winapi для рендеринга текста? 22.04.2011

  • 4

    Успех - смотрите на красную строку:

    http://i54.tinypic.com/2r60dc3.png

    Используя метод, который я создал здесь .

    Интересно, что мне все равно пришлось указать размер шрифта 15. Я не уверен, что это связано с точкой и пикселем, хотя, как говорится в документах:

    › 0: Преобразователь шрифтов преобразует это значение в единицы устройства и сопоставляет его с высотой ячейки доступных шрифтов.

    ‹ 0: Преобразователь шрифтов преобразует это значение в единицы устройства и сопоставляет его абсолютное значение с высотой символов доступных шрифтов.

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

    22.04.2011

    5

    Как уже указывал Нед, не очень правильно пытаться получить такой же результат из какой-то библиотеки рендеринга. Если вы хотите точно такой же нативный вид, вы пытаетесь добраться до внутренней функциональности Windows, и это то, что вы уже сделали, как я вижу из другого вашего поста, и это очень интересно.

    Если говорить о реалистичной отрисовке текста на экране в целом, то здесь есть несколько важных нюансов. Во-первых, все форматы векторных шрифтов изначально разрабатываются не для экрана, а исключительно для типографики, а это два больших отличия. Для экрана все, что вам нужно, это растровое изображение, а именно 8-битная информация альфа-канала, которую вы затем смешиваете с фоном экрана вместе со значениями пикселей. Чтобы все заработало, вам нужно буквально скопировать файл TTF в набор растровых изображений.

    И вот два пути, грубо говоря:

    • Извлечение глифов с высоким разрешением в ЧБ (1 бит). Например. Растровых изображений ~600px будет достаточно для большинства случаев. Затем вы можете создавать строки и изменять их размер в зависимости от потребностей.

    • Извлеките их непосредственно в целевое разрешение в виде 8-битных массивов. В этом случае вы не можете изменять их размер, а только строить строки, просто помещая эти 8-битные массивы в альфа-канал и размещая вдоль строки.

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

    Лучше придерживаться первого шага, потому что второго подхода вы можете достичь и с растровыми изображениями высокого разрешения, не нужно каждый раз растеризовать их. Для небольших размеров для лучшей точности расстояния вы также можете генерировать «сдвинутые» глифы, что означает те же глифы, но сдвинутые на 1/2 или 1/3 пикселя в исходном изображении с высоким разрешением. Это снова потребует немного другой процедуры построения строки.

    Важное примечание о размере: не существует такой точной вещи, как размер шрифта. В типографике это размер квадрата Em и не имеет прямой связи с x-высотой шрифта. Более того, если я выполняю рендеринг или передискретизацию растрового изображения, я оперирую только размером пикселя Em-квадрата (границы всего растрового изображения) и коэффициентом понижения разрешения, если я использую его для получения небольших растровых изображений. Реальный размер x-height может быть приблизительно рассчитан только для справки.

    Для вашего случая растровых изображений без сглаживания эти небольшие растровые изображения должны быть уже включены в файл шрифта, по крайней мере, для собственных шрифтов, таких как Arial и Times. IIRC Они хранятся внутри TTF для определенных небольших размеров, обычно 7–16 pt, и в виде 1-битных масок. Вопрос только в том, как их извлечь или получить к ним из приложения. Я действительно не знаю, я рассматриваю их просто как устаревшие вещи. Я больше занимаюсь реалистичной проблематикой рендеринга.

    12.11.2016

    6

    Несмотря на то, что в документации PIL указано, что размер указан в пунктах, PIL также использует 72DPI, поэтому, если вы преобразуете размер в пунктах в размер в пикселях (путем деления на 0,75), а затем используете math.ceil() для преобразования в целое число, шрифт будет отображаться правильно и похоже (но, конечно, не совсем) на то, что отображается в окнах.

    27.08.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..