Вычисление среднего значения двух цветов

Это лишь незначительно связано с программированием - гораздо больше нужно сделать с цветами и их представлением.

Я работаю над приложением очень низкого уровня. У меня есть массив байтов в памяти. Это персонажи. Они были визуализированы со сглаживанием: они имеют значения от 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 кажется, что текст имеет зеленую «ауру».

Тест, не самый лучший

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

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


person F. P.    schedule 30.12.2010    source источник


Ответы (3)


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

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

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

Редактировать:

Это выглядит неправильно:

(255.0 - (float) intensity/255.0)

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

(255.0 - (float) intensity)/255.0
person OJ.    schedule 30.12.2010
comment
Или, выражаясь в терминах исходного кода: transfer = (int) ((1.0 - intensity/255.0) * color.red + intensity/255.0 * pixel.red); - person Mark Ransom; 31.12.2010
comment
P.S. отображать все символы шрифта на поверхности за пределами экрана - я думаю, что это и есть glyphs. - person Mark Ransom; 31.12.2010
comment
Меня не волнует производительность, так как это экспериментальное академическое приложение. Но спасибо за ваш вклад! Я попробую это. - person F. P.; 31.12.2010

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

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

person EnabrenTane    schedule 30.12.2010

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

Я бы переработал алгоритм, думая о блочном смешивании.


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

person 9dan    schedule 30.12.2010