2016-05-17 6 views
2

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

После долгих проб и ошибок (и некоторые чтения), мне удалось сделать следующее:

procedure OpacityRectangle(ACanvas: TCanvas; ARect: TRect; AColor: TColor; 
    AOpacity: Integer); 
var 
    BlendFunc: BLENDFUNCTION; 
    W, H: Integer; 
    Bitmap: TBitmap; 
begin 
    W := ARect.Width; 
    H := ARect.Height; 

    BlendFunc.BlendOp := AC_SRC_OVER; 
    BlendFunc.BlendFlags := 0; 
    BlendFunc.SourceConstantAlpha := AOpacity; 
    BlendFunc.AlphaFormat := 0; 

    Bitmap := TBitmap.Create; 
    try 
    Bitmap.PixelFormat := pf32Bit; 
    Bitmap.SetSize(W, H);  
    BitBlt(Bitmap.Canvas.Handle, ARect.Left + W, ARect.Top + H, W, H, 
     ACanvas.Handle, 0, 0, SRCCOPY); 
    AlphaBlend(ACanvas.Handle, ARect.Left, ARect.Top, 
     W, H, Bitmap.Canvas.Handle, 0, 0, W, H, BlendFunc); 
    finally 
    Bitmap.Free; 
    end; 
end; 

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

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

ответ

8

В настоящее время вы используете белый цвет, причина, по которой вы думаете, что это серый, - это прозрачность. Вы можете проверить это, передав 255 как «AOpacity», вы увидите белый прямоугольник.

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

... 
    try 
    Bitmap.PixelFormat := pf32Bit; 
    Bitmap.Canvas.Brush.Color := AColor; // <- set tint color 
    Bitmap.SetSize(W, H); 
    AlphaBlend(ACanvas.Handle, ARect.Left, ARect.Top, 
     ... 


В случае Lazarus, явно окрасить поверхность растрового изображения, FPC графика не чтит цвет кисти при увеличении битовой карты (следовательно, точечный рисунок изначально черный).

.. 
    try 
    Bitmap.PixelFormat := pf32Bit; 
    Bitmap.SetSize(W, H); 
    Bitmap.Canvas.Brush.Color := AColor; 
    Bitmap.Canvas.FillRect(Bitmap.Canvas.ClipRect); 
    AlphaBlend(ACanvas.Handle, ARect.Left, ARect.Top, 
     ... 
+0

Спасибо за ваше объяснение и ответ, к сожалению, я не понял, что я оставил тег «Lazarus» вне вопроса (не ваша ошибка). В Lazarus это, похоже, не работает с использованием 'JwaWindows.AlphaBlend()', и сейчас я не могу тестировать Delphi, это, вероятно, проблема с Lazarus, но мне нужно будет экспериментировать еще немного. – Craig

+0

@Craig - проверено. Проблема заключается в том, что fpc-графика не использует цвет кисти при изменении размера растрового изображения. Сначала задайте размер, затем установите цвет кисти, затем вставьте bitmap.canvas.fillrect с прямоугольником (0, 0, W, H). Тогда это работает. –

+0

Теперь, отлично работая благодаря Sertac, спасибо за разъяснение некоторых вещей, например, почему я понял, что альфа-цвет по умолчанию был серым, и почему мне даже не нужно было использовать BitBlt. – Craig

Смежные вопросы