2010-12-30 2 views
4

Это лишь незначительное программирование, связанное с этим - имеет гораздо больше возможностей для w/colors и их представления.Вычисление «среднего» двух цветов

Я работаю над очень низким уровнем приложения. У меня есть массив байтов в памяти. Это персонажи. Они были обработаны сглаживанием: они имеют значения от 0 до 255, 0 - полностью прозрачные и 255 полностью непрозрачные (альфа, если хотите).

У меня возникли проблемы с созданием алгоритма для рендеринга этого шрифта. Я делаю следующее для каждого пикселя:

  // intensity is the weight I talked about: 0 to 255 
      intensity = glyphs[text[i]][x + GLYPH_WIDTH*y]; 
      if (intensity == 255) 
       continue; // Don't draw it, fully transparent 
      else if (intensity == 0) 
       setPixel(x + xi, y + yi, color, base); // Fully opaque, can draw original color 
      else { // Here's the tricky part 
       // Get the pixel in the destination for averaging purposes 
       pixel = getPixel(x + xi, y + yi, base); 
       // transfer is an int for calculations 
       transfer = (int) ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.red + (float) pixel.red)/2); // This is my attempt at averaging 
       newPixel.red = (Byte) transfer; 
       transfer = (int) ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.green + (float) pixel.green)/2); 
       newPixel.green = (Byte) transfer; 
       // transfer = (int) ((float) ((float) 255.0 - (float) intensity)/255.0 * (((float) color.blue) + (float) pixel.blue)/2); 
       transfer = (int) ((float)((float) (255.0 - (float) intensity/255.0) * (float) color.blue + (float) pixel.blue)/2); 
       newPixel.blue = (Byte) transfer; 
       // Set the newpixel in the desired mem. position 
       setPixel(x+xi, y+yi, newPixel, base); 
      } 

Результаты, как вы можете видеть, меньше, чем хотелось бы. Это очень увеличенное изображение, при масштабе 1: 1 похоже, что текст имеет зеленую «ауру».

The test, less than great

Любая идея о том, как правильно вычислить это было бы весьма признателен.

Спасибо за ваше время!

ответ

4

Вам необходимо смешать цвета фона и переднего плана. А-ля:

pixelColour = newColour * intensity + backgroundColour * (1 - intensity) 

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

Edit:

Это выглядит не так:

(255.0 - (float) intensity/255.0) 

Это должно быть вместо этого:

(255.0 - (float) intensity)/255.0 
+0

+1 линейная интерполяция, вероятно, лучше. – EnabrenTane

+1

Или, чтобы выразить это в терминах исходного кода: 'transfer = (int) ((1.0 - интенсивность/255.0) * color.red + интенсивность/255.0 * pixel.red);' –

+1

P.S. msgstr "отобразить все символы шрифта на поверхность вне экрана". Я думаю, что это то, что означает "глифы". –

1

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

Я понимаю, что вы, кажется, не используете OpenGL, но this chapter может помочь объяснить некоторые из теорий. Желаю, чтобы у меня был лучший ответ, но, надеюсь, это указывает на то, что вы в правильном направлении. Моя первая попытка состояла бы в том, чтобы отключить Antialiasing, поскольку он, кажется, приносит больше вреда, чем пользы. Вероятно, есть лучшее решение, чем это.

1

Может быть слишком сложно выполнить альфа-смешение пикселей по пикселю, потому что текущее значение пикселя изменяет значение следующего пикселя.

Я бы пересмотрел алгоритм с мышлением бокового смешивания.

С многими getPixel, призывающими к одному глифу, вы не можете создать надлежащее целевое изображение.