Алгоритмы уменьшения масштаба растровых шрифтов - PullRequest
2 голосов
/ 15 ноября 2010

Это продолжение этого вопроса .

Я работаю над приложением низкого уровня C, где мне нужно рисовать текст.Я решил сохранить шрифт, который я хочу использовать, в виде массива (черно-белый, возможно, каждый символ 128х256), а затем уменьшил бы его до нужных мне размеров с помощью некоторого алгоритма (например, в градациях серого, чтобы у меня был сыройсглаживание шрифтов).

Примечание: это игрушечный проект, не обращайте внимания на такие вещи, как выполнение вычислений во время выполнения или нет.

Вопрос в том, какой алгоритм?

Iпосмотрел 2xSaI, но это довольно сложно.Я хотел бы кое-что, для чего я могу прочитать описание и сам разработать код (я новичок и программирую на C / C ++ чуть менее года).

Предложения, кто-нибудь?

Спасибо за потраченное время!

Редактировать: Обратите внимание, что ввод черно-белый, вывод должен быть сглажен в оттенках серого

Ответы [ 5 ]

4 голосов
/ 15 ноября 2010

Определите прямоугольник на исходном изображении, который будет соответствовать целевому пикселю. Например, если исходное изображение имеет размер 50x100, а место назначения - 20x40, верхний левый пиксель в месте назначения соответствует прямоугольнику от (0,0) до (2.2,2.2) на исходном изображении. Теперь сделайте среднюю площадь по этим пикселям:

  • Площадь составляет 2,2 * 2,2 = 4,84. Вы масштабируете результат на 1 / 4,84.
  • Пиксели в точках (0,0), (0,1), (1,0) и (1,1) весят по 1 единице.
  • Пиксели в точках (0,2), (1,2), (2,0) и (2,1) весят по 0,2 единицы (поскольку прямоугольник покрывает только 20% из них).
  • Пиксель в (2,2) весит 0,04 (потому что прямоугольник покрывает только 4% его).
  • Общий вес, конечно, 4 * 1 + 4 * 0,2 + 0,04 = 4,84.

Это было легко, потому что вы начали с исходного и конечного пикселей, выровненных по краям изображения. Как правило, у вас будет частичное покрытие на всех 4 сторонах / 4 углах скользящего прямоугольника.

Не утруждайте себя алгоритмами, отличными от усреднения по площади для уменьшения масштаба. Большинство из них просто неправильно (они приводят к ужасному алиасингу, по крайней мере, с коэффициентом, меньшим 1/2), а те, которые не являются просто неправильными, являются более болезненными для реализации и, вероятно, победили не даст вам лучших результатов.

3 голосов
/ 15 ноября 2010

Считайте, что ваше изображение является растровым изображением черно-белого изображения.Для простоты мы рассмотрим это char Letter[N][M], когда допустимые значения 0 и 1.Теперь учтите, что вы хотите уменьшить его до unsigned char letter[n][m].Это будет означать, что каждый пиксель в оттенках серого из letter будет вычисляться как количество белых пикселей в большом растровом изображении:

char Letter[N][M];
unsigned char letter[n][m];
int rect_sz_X = N / n; // the size of rectangle that will map to a single pixel
int rect_sz_Y = M / m; // in the downscaled image
int i, j, x, y;
for (i = 0; i < n; i++) for (j = 0; j < m; j++){
    int sum = 0;
    for (x = 0; x < rect_sz_X; x++) for (y = 0; y < rect_sz_Y; y++)
        sum += Letter[i*rect_sz_X + x][j*rect_sz_Y + y];
    letter[n][m] = ( sum * 255) / (rect_sz_X * rect_sz_Y);
};

Обратите внимание, что прямоугольники, которые создают пиксели, могут перекрываться (в случае, если размеры ненеделимы).Чем больше исходное изображение, тем лучше.

2 голосов
/ 15 ноября 2010

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

1 голос
/ 15 ноября 2010

Все довольно просто.Если все, что у вас есть, это растровый шрифт вместо контурного, то у вас есть очень ограниченный выбор при выборе цвета пикселя сглаживания.Например, если размер точки растрового шрифта ровно в четыре раза больше требуемого размера точки отображения, вы можете получить только 16 различных вариантов выбора.Количество «освещенных» пикселей в прямоугольнике отображения 4x4.

Работа с дробным отображением - это упражнение по программированию, но не улучшение качества.

0 голосов
/ 15 ноября 2010

Если допустимо ограничить масштабирование кратными 2 (50%, 25%, 12,5% и т. Д.), То очень простой и довольно хороший алгоритм состоит в том, чтобы создать каждый пиксель уменьшенного масштаба в качестве большинства голосов всехисходные пиксели.Например, при 50% квадрат из четырех пикселей образует один уменьшенный масштаб изображения: если ноль или один из них включен, то выход отключен;если три или четыре включены, то выход включен.Художественный кейс (для двух пикселей), либо всегда включайте, либо выключайте, либо смотрите на другие окружающие пиксели для разрыва связи

...