2013-03-14 18 views
9

Voglio disegnare immagini piuttosto complesse con rettangoli trasparenti alfa e immagini trasparenti alfa. There is GDI+ wrapper from Mitov, ma non sembra supportare i file BMP a 32 bit più li ridimensiona e la documentazione è terribile. I BMP sono molto più veloci dei PNG quindi voglio usarli. There is SynGDI wrapper of GDI+, ma sembra molto semplice e non c'è documentazione per questo. C'è anche questo trucco per GDI:Come disegnare trasparente con trasparenza alfa in Delphi?

procedure DrawAlphaAPI(Source: TBitmap; Destination: TCanvas; 
    const X, Y: Integer; const Opacity: Byte = 255); 
var BlendFunc: TBlendFunction; 
begin 
    BlendFunc.BlendOp := AC_SRC_OVER; 
    BlendFunc.BlendFlags := 0; 
    BlendFunc.SourceConstantAlpha := Opacity; 

    if Source.PixelFormat = pf32bit then 
    BlendFunc.AlphaFormat := AC_SRC_ALPHA 
    else 
    BlendFunc.AlphaFormat := 0; 

    Windows.AlphaBlend(Destination.Handle, X, Y, Source.Width, Source.Height, 
    Source.Canvas.Handle, 0, 0, Source.Width, Source.Height, BlendFunc); 
end; 

Ma quando io lo chiamo con Opacità = 255 trae bitmap a 32 bit non correttamente (qualcosa come la metà sono trasparenti dove dovrebbero essere completamente). Non voglio usare Scanline per rendere i pixel trasparenti in quanto ciò sarà troppo complicato per disegnare in questo modo tutti i rettangoli trasparenti. Anche io GDI + sottile dovrebbe essere più veloce sui computer moderni, ho ragione?

Quindi la domanda è: come disegnare facilmente un rettangolo e una bitmap trasparenti alfa (senza tonnellate di codice)?

Delphi preferito: 7. Ho anche il 2005 e l'XE3 ma dal momento che 7 è un demone della velocità, vorrei che qualcosa funzioni dal 7 in poi.

+1

Se si potrebbe usare [ 'questo wrapper'] (http://www.bilsen.com/gdiplus/index.shtml) che supporta Delphi 2009 fino, si potrebbe scrivere [' codice come questo!] (http://pastebin.com/fcjtHKen) che sembra abbastanza complicato, ma è necessario sapere che è possibile modificare il ['color adjustment'] (http://www.codeproject.com/Articles/3772/ColorMatrix-Basics-Simple-Image-Color-Adjustment) con quella matrice di colori e che sto caricando un file per essere mixato alfa in quel codice (potreste ad esempio creare un 'GPBitmap' da un oggetto' TBitmap' passato). – TLama

+0

@TLama Grazie, questo GDI + sembra il migliore finora. L'altro è schifoso. Uno di Progdigy non si compila su (7, né 2005 né XE3), quello di Mitov distrugge le immagini dopo averle disegnate, quella di Synopse è incompleta. – Tom

+1

FWIW: Ho trovato [questi articoli] (http://itinerantdeveloper.blogspot.de/search/label/alpha%20transparency) abbastanza interessante. –

risposta

8

Se si prepara la TBitmap ordinaria, è possibile utilizzare qualsiasi implementazione GDI + semplicemente assegnando bmp.Canvas.Handle. Il problema nella compilazione potrebbe essere causato da una vecchia versione di DirctDraw nella cartella, è sufficiente rimuoverlo.

implementation 

uses GDIPAPI, GDIPOBJ; 
{$R *.dfm} 

Procedure PrepareBMP(bmp: TBitmap; Width, Height: Integer); 
var 
    p: Pointer; 
begin 
    bmp.PixelFormat := pf32Bit; 
    bmp.Width := Width; 
    bmp.Height := Height; 
    bmp.HandleType := bmDIB; 
    bmp.ignorepalette := true; 
    bmp.alphaformat := afPremultiplied; 
    // clear all Scanlines 
    p := bmp.ScanLine[Height - 1]; 
    ZeroMemory(p, Width * Height * 4); 
end; 

procedure TForm2.Button1Click(Sender: TObject); 
var 
    bmp: TBitmap; 
    G: TGPGRaphics; 
    B: TGPSolidBrush; 
begin 
    bmp := TBitmap.Create; 
    try 
    PrepareBMP(bmp, 300, 300); 
    G := TGPGRaphics.Create(bmp.Canvas.Handle); 
    B := TGPSolidBrush.Create(MakeColor(100, 255, 0, 0)); 
    try 
     G.SetSmoothingMode(SmoothingModeHighQuality); 
     G.FillEllipse(B, MakeRect(0.0, 0, 300, 300)); 
     B.SetColor(MakeColor(100, 0, 255, 128)); 
     G.FillEllipse(B, MakeRect(40.0, 40, 260, 260)); 
    finally 
     B.Free; 
     G.Free; 
    end; 
    // draw overlapping in Form Canvas to display transparency 
    Canvas.Draw(0, 0, bmp); 
    Canvas.Draw(100, 100, bmp); 
    finally 
    bmp.Free; 
    end; 
end; 

DEMO

+0

Grazie, bummi! Non sapevo di bmp.AlphaFormat, perché prima di acquistare XE3 ho lavorato su Delphis più vecchi e non c'erano cose del genere. Ma ora, quando faccio bmp.AlphaFormat: = afDefined; Normalmente carico solo bitmap a 32 bit e Canvas.Draw()! – Tom

+0

Ho rimosso anche DirectDraw.pas e la compilazione GDI di Progdidy va bene (almeno in XE3), grazie! – Tom

Problemi correlati