यह प्रश्न SO पर मेरे earlier question से संबंधित है।Alphablend और TransparentBlt
मैं अल्फा के साथ दो परतों को जोड़ना चाहता हूं जो केवल स्रोत परत के एक विशिष्ट भाग पर लागू होते हैं। एक तरीका मैंने कोशिश की थी SourceConstantAlpha को $ ff (और फ़ंक्शन को स्रोत परत में अल्फा चैनल का उपयोग करें) सेट करना था।
इस तरह के काम - हालांकि धीमा (मुझे लगता है कि मैं स्कैनलाइन का उपयोग करके इसे तेज कर सकता हूं), इस तरह का हिस्सा यह है कि मैं यह नहीं समझ सकता कि अल्फा चैनल को सेट करना है या नहीं। प्रलेखन पता चलता है कि गणना है:
st.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
मुझे लगता है कि काम से कुछ अलग मूल्यों की कोशिश की है, लेकिन मेरा पहला सवाल यह है: मैं अल्फा मूल्य की गणना कैसे करूँ?
कुछ अन्य SO प्रश्न पढ़ने के बाद, मैं ट्रांसपेरेंटब्लैट फ़ंक्शन में आया, जो मास्किंग अच्छी तरह से (और तेज़) लेकिन पारदर्शिता नहीं करता है, क्या को इन दो कॉलों को एक साथ जोड़ने का एक तरीका है (शायद एक तीसरी परत का उपयोग करना)?
unit MainWnd;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ControlsEx;
type
{------------------------------------------------------------------------------}
TfrmMain = class(TForm)
PaintBox1: TPaintBox;
procedure PaintBox1Paint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
{..............................................................................}
procedure copyToAlpha(const in_bitmap : TBitmap; const in_transparentColor : TColor;
const in_transparency : integer);
var
x : integer;
y : integer;
p : integer;
begin
ASSERT(in_bitmap.PixelFormat = pf32bit);
for x := 0 to in_bitmap.Width - 1 do
begin
for y := 0 to in_bitmap.Height - 1 do
begin
p := in_bitmap.Canvas.Pixels[x, y];
if TColor(p) <> in_transparentColor then
begin
in_bitmap.Canvas.Pixels[x, y] := p or (in_transparency shl 24);
end
else
in_bitmap.Canvas.Pixels[x, y] := p or ($ff shl 24);
end;
end;
end;
{..............................................................................}
procedure alphaBlendTest(
const in_target : TCanvas;
const in_width : integer;
const in_height : integer);
const
BARSIZE = 30;
var
bitmap : TBitmap;
r : TRect;
blendFn : BLENDFUNCTION;
ret : Boolean;
begin
blendFn.BlendOp := AC_SRC_OVER;
blendFn.SourceConstantAlpha := $ff;
blendFn.BlendFlags := 0;
blendFn.alphaFormat := AC_SRC_ALPHA;
bitmap := TBitmap.Create;
try
bitmap.Width := in_width;
bitmap.Height := in_height;
bitmap.PixelFormat := pf32bit;
bitmap.HandleType := bmDIB;
bitmap.TransparentColor := clFuchsia;
bitmap.Transparent := true;
bitmap.Canvas.Brush.Color := clFuchsia;
bitmap.Canvas.FillRect(Bounds(0, 0, in_width, in_height));
bitmap.Canvas.Brush.Color := clGreen;
r := Bounds(
in_width div 2 - (in_width div 3) div 2,
0,
(in_width div 3) + 1,
BARSIZE + 1);
bitmap.Canvas.Rectangle(r);
// done drawing
//copyToAlpha(bitmap, clFuchsia, 1);
ret := Windows.TransparentBlt(
in_target.Handle,
0,
0,
in_width,
in_height,
bitmap.Canvas.Handle,
0,
0,
in_width,
in_height,
clFuchsia);
//blendFn);
ASSERT(ret);
finally
bitmap.Free;
end;
end;
{..............................................................................}
procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
r: TRect;
begin
PaintBox1.Canvas.Brush.Color := clBlue;
r := Bounds(0, 0, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
PaintBox1.Canvas.FillRect(r);
PaintBox1.Canvas.Brush.Color := clRed;
PaintBox1.Canvas.Ellipse(0, 0, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
alphaBlendTest(PaintBox1.Canvas, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
end;
end.
आप गुणक y प्रत्येक पिक्सेल की आर, जी, बी आपके वांछित अल्फा के साथ और 'अल्फाब्लेंड' के लिए 255 तक विभाजित करें, बेशक पिक्सेल के अल्फा को अल्फा मान पर भी सेट करें। मैं 'पारदर्शी बीएलटी' के बारे में सवाल नहीं समझता, पारदर्शिता कैसे अच्छी तरह से नहीं है? –
@ सर्टैक ओपी में एक बिटमैप है जो आंशिक रूप से एक पारदर्शी रंग से बना है। पारदर्शी हिस्सों को गंतव्य कैनवास पर बरकरार रखना है, खींचे गए हिस्सों को गंतव्य कैनवास में वर्णित किया जाना है। – NGLN