2012-10-03 4 views
1

윈도우 알바 블렌드 API 호출을 사용하여 두 개의 캔버스를 함께 사용하려고합니다. 먼저 주 캔버스 (대상)에 그림을 그린 다음 TBitmap을 사용하여 다른 캔버스를 인스턴스화하고 그 위에 그림을 그린 다음 두 그림을 혼합합니다 (여기에 대한 답변을 따라).AlphaBlend가 항상 false를 반환하는 이유는 무엇입니까 (캔버스에서 그리기)?

그러나 나는 항상 false를 반환한다는 것을 알았습니다. 처음에는 소스와 대상에 대해 잘못된 핸들을 전달하는 것과 관련이 있다고 생각했지만 실제로는 알 수 없습니다. 뭐가 될수 있었는지?

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 alphaBlendf(
     const in_target  : TCanvas; 
     const in_transperancy : integer; 
     const in_color  : TColor; 
     const in_rect   : TRect; 
     const in_width  : integer; 
     const in_height  : integer); 
var 
    w   : integer; 
    h   : integer; 
    bitmap  : TBitmap; 
    blendFn : BLENDFUNCTION; 
    ret  : boolean; 
begin 
    blendFn.BlendOp    := AC_SRC_OVER; 
    blendFn.SourceConstantAlpha := 80; 

try 
    w := in_rect.Right - in_rect.Left - 1; 
    h := in_rect.Bottom - in_rect.Top - 1; 

    bitmap     := TBitmap.Create; 
    bitmap.PixelFormat  := pf32bit; 
    bitmap.Width    := w; 
    bitmap.Height    := h; 
    bitmap.Canvas.Brush.Color := in_color; 

    bitmap.Canvas.Rectangle(in_rect); 

    ret := Windows.AlphaBlend(
     in_target.Handle, 
     0, 
     0, 
     in_width, 
     in_height, 
     bitmap.Canvas.Handle, 
     0, 
     0, 
     in_width, 
     in_height, 
     blendFn); 

    if ret then in_target.TextOut(0, 0, 'ok') 
      else in_target.TextOut(0, 0, 'fail'); 
    finally 
    bitmap.Free; 
    end; 
end; 

{..............................................................................} 
procedure TfrmMain.PaintBox1Paint(Sender: TObject); 
var 
    r: TRect; 
begin 
    PaintBox1.Canvas.Brush.Color := $FCFFB5; 
    PaintBox1.Canvas.FillRect(r); 

    r := Rect(0, 0, 100, 100); 
    alphaBlendf(PaintBox1.Canvas, 0, clLime, r, PaintBox1.ClientWidth, PaintBox1.ClientHeight); 
end; 

end. 

답변

7

코드에 여러 가지 오류가 있습니다.

BLENDFUNCTION의 일부 회원을 작성하지 않았습니다. 그들은 선택 사항이 아니며 값을 제공합니다.

비트 맵 개체 생성은 try 문 앞에 있어야합니다 (이것은 AlphaBlend이 실패한 이유와 관련이 없습니다).

AlphaBlend 함수가 원본보다 더 섞을 것을 요구합니다. 즉, 비트 맵이 99x99이지만 API가 105x105로 혼합되기를 원합니다.

페인트 상자의 페인트 핸들러에서 임의의 사각형을 채우고 있습니다 (은 초기화되지 않았습니다).

procedure alphaBlendf(
     const in_target  : TCanvas; 
     const in_transperancy : integer; 
     const in_color  : TColor; 
     const in_rect   : TRect; 
     const in_width  : integer; 
     const in_height  : integer); 
var 
    w   : integer; 
    h   : integer; 
    bitmap  : TBitmap; 
    blendFn : BLENDFUNCTION; 
    ret  : boolean; 
begin 
    blendFn.BlendOp    := AC_SRC_OVER; 
    blendFn.BlendFlags   := 0; 
    blendFn.SourceConstantAlpha := 80; 
    blendFn.AlphaFormat   := 0; 

    bitmap     := TBitmap.Create; 
    try 
    w := in_rect.Right - in_rect.Left - 1; 
    h := in_rect.Bottom - in_rect.Top - 1; 

    bitmap.PixelFormat  := pf32bit; 
    bitmap.Width    := w; 
    bitmap.Height    := h; 
    bitmap.Canvas.Brush.Color := in_color; 

    bitmap.Canvas.Rectangle(in_rect); 

    ret := Windows.AlphaBlend(
     in_target.Handle, 
     0, 
     0, 
     in_width, 
     in_height, 
     bitmap.Canvas.Handle, 
     0, 
     0, 
     bitmap.width, 
     bitmap.height, 
     blendFn); 

    if ret then in_target.TextOut(0, 0, 'ok') 
      else in_target.TextOut(0, 0, 'fail'); 
    finally 
    bitmap.Free; 
    end; 
end; 

{..............................................................................} 
procedure TfrmMain.PaintBox1Paint(Sender: TObject); 
var 
    r: TRect; 
begin 
    PaintBox1.Canvas.Brush.Color := $FCFFB5; 
    r := Rect(0, 0, 100, 100); 
    PaintBox1.Canvas.FillRect(r); 

    alphaBlendf(PaintBox1.Canvas, 0, clLime, r, 
     PaintBox1.ClientWidth, PaintBox1.ClientHeight); 
end; 
+0

나에게서 붙여 넣는 코드가 엉성한 코드 * *; 완벽하게 작동합니다, 감사합니다! – wmercer

+0

여러분을 환영합니다! –

관련 문제