SharpDX /DirectX: как визуализировать текст в прозрачном BitmapRenderTarget?

Я пытаюсь сделать текст BitmapRenderTarget, очищенный прозрачным цветом.

Мой TextBox нарисован сам по себе SharpDX.Direct2D1.BitmapRenderTarget, который я создаю следующим образом:

var bitmapRenderTarget = new SharpDX.Direct2D1.BitmapRenderTarget(renderTarget,
    SharpDX.Direct2D1.CompatibleRenderTargetOptions.None, null, null, null);

Как вы можете видеть, я не меняю формат пикселей BitmapRenderTarget. Формат пикселя лежащего ниже SharpDX.Direct2D1.RenderTarget, на который я рисую свой TextBox через DrawBitmap, определяется в следующем коде:

renderTargetProperties = new SharpDX.Direct2D1.RenderTargetProperties()
{
    PixelFormat = new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.Unknown,
    SharpDX.Direct2D1.AlphaMode.Premultiplied)
};

Вот код, который дает визуальные результаты:

// In the case 1: opaque white background
bitmapRenderTarget.Clear(SharpDX.Color.White);
...

// In the case 2: white background with 50% transparency
bitmapRenderTarget.Clear(new SharpDX.Color4(1f, 1f, 1f, 0.5f));
...

// In the case 3: fully transparent background
bitmapRenderTarget.Clear(SharpDX.Color.Transparent);
...

// The color of textBrush in all these cases is the same solid Black.
bitmapRenderTarget.DrawTextLayout(vector, textLayout, textBrush, ...);

Результаты:

Плохой перевод текста

Как вы можете видеть, альфа-значение цвета текста каким-то образом связано с цветом в четком цвете. Черная линия вокруг текста - это курсор, и он нарисован так, как должен.

Как исправить эту проблему?

3 голоса | спросил Injector 15 PMpWed, 15 Apr 2015 12:14:06 +030014Wednesday 2015, 12:14:06

1 ответ


1

Я не знаком ни с SharpDX, ни с Direct2D.

Однако, я предполагаю, что то, что вы видите, вызвано AlphaMode.PremultipliedAlpha.

Это уравнение смешивания для предварительно умноженного альфа:

  

blend (source, dest) = source.rgb + (dest.rgb * (1 - source.a))

Как вы можете видеть, альфа-канал источника не учитывается, так как режим предполагает, что цветовые каналы источника уже были умножены на его непрозрачность.

В вашем примере источником является непрозрачный черный (r = 0, g = 0, b = 0, a = 1) текст, который вы выполняете, а dest - белый фон и его (изменяющаяся) непрозрачность.

Для непрозрачного белого фона (r = 1, g = 1, b = 1, a = 1) вы получаете:

  

source.rgb + (dest.r * (1 - source.a)) = (0,0,0) + (1,1,1) * (1-1) =   (0,0,0) => черный

Для 50% непрозрачного белого (r = 1, g = 1, b = 1, a = 0,5) вы получаете:

  

source.rgb + (dest.r * (1 - source.a)) = (0,0,0) + (1,1,1) * (1-0,5) =   (0,5,0,5,0,5) => серый

И для полностью полупрозрачного белого (r = 1, g = 1, b = 1, a = 0) вы получаете:

  

source.rgb + (dest.r * (1 - source.a)) = (0,0,0) + (1,1,1) * (1-0) =   (1,1,1) => белый

Как вы можете видеть, это не «затухание», а скорее «отбеливание», которое происходит здесь.

Короче говоря, я думаю, что исправление, которое вы ищете, это изменить режим смешивания из PremultipliedAlpha в AlphaBlend.

Дальнейшее чтение: http://blogs.msdn.com/b /shawnhar/archive/2009/11/06/premultiplied-alpha.aspx

ответил SmoCoder 16 PMpThu, 16 Apr 2015 16:53:53 +030053Thursday 2015, 16:53:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132