Entwickler-Ecke
Multimedia / Grafik - Alphablend zweier TGraphics
elundril - Mo 26.03.07 17:44
Titel: Alphablend zweier TGraphics
Ein überarbeiteter
Library-Eintrag ist hier [
http://www.delphi-library.de/viewtopic.php?t=109281] zu finden.
Alphablend zweier Bilder
Folgernder Code dient dazu zwei TGraphic typen (also Bitmap, jpeg, usw) mittels Alphablend zu einem Bitmap zu verschmeltzen.
Die Beiden Images (Image1 und Image2) sind typen die von TGraphic abgeleitet sind und müssen existieren.
Ebenso wie das ResultBitmap das übergeben werden muss. In dieses wird dann das Alphablendbild "geschrieben".
Mit den AlphaValue wird dann der Wert beschrieben welches Bild stärker werden soll. Mit 0 wird nur das erste Bild gezeigt und mit 255 nur das zweite.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure AlphaImgs(Image1, Image2: TGraphic; ResultBitmap: TBitmap; AlphaValue: Byte); type pixel = Array [0..2] of byte; var bmpImg1, bmpImg2: TBitmap; x,y,h,w: integer; p1, p2: ^pixel; begin bmpImg1:=TBitmap.Create; bmpImg2:=TBitmap.Create; try bmpImg1.Height:=Image1.Height; bmpImg2.Height:=Image2.Height; bmpImg1.Width:=Image1.Width; bmpImg2.Width:=Image2.Width; bmpImg1.PixelFormat:=pf24bit; bmpImg2.PixelFormat:=pf24bit; bmpImg1.Canvas.Draw(0,0,Image1); bmpImg2.Canvas.Draw(0,0,Image2); h := Min(bmpImg1.Height, bmpImg2.height); w := Min(bmpImg1.Width, bmpImg2.Width); for y :=0 to h-1 do begin p1 := bmpImg1.ScanLine[y]; p2 := bmpImg2.ScanLine[y]; for x:= 0 to w-1 do begin p1^[0] := ((p1^[0]*(AlphaValue+1) + (p2^[0]*(256-AlphaValue))) shr 8); p1^[1] := ((p1^[1]*(AlphaValue+1) + (p2^[1]*(256-AlphaValue))) shr 8); p1^[2] := ((p1^[2]*(AlphaValue+1) + (p2^[2]*(256-AlphaValue))) shr 8); inc(p1); inc(p2); end; end; ResultBitmap.Assign(bmpImg1); finally bmpImg1.Free; bmpImg2.Free; end; end; |
Aufrufen könnte man nun diese prozedur wiefolgt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TfrmMain.btnblendClick(Sender: TObject); var bmpresult:TBitmap; begin ImageResult.Picture.Assign(nil); bmpresult:=TBitmap.Create; AlphaImgs(Image1.Picture.Graphic,Image2.Picture.Graphic,bmpresult,Byte(sbAlpha.Position)); ImageResult.Picture.Assign(bmpresult); bmpresult.Free; end; |
freu mich auf Kritik.
ToDo: Das erste Bild fix als Hintergrund verwenden und das zweite Darüberblenden, ohne das erste abzuschneiden.
ToDo: Das ganze dann noch variabel machen sodass man dem programm sagen kann bei welchen koordinaten das zweite bild darübergeblendet werden soll
lg elundril
//edit: hab den Code zum Alphablenden der einzelnen Bitmapfarben gekürzt.
//edit: Try-Finally Block eingefügt
//edit: Fehler mit Klammern beseitigt
Angehängt ist ein beispielprogramm. Es wäre nett wenn mein Name erwähnt wird bei Programmen die diese prozedur verwenden.
Blawen - Do 29.03.07 21:20
Zitat: |
Angehängt ist ein beispielprogramm. Es wäre nett wenn mein Name erwähnt wird bei Programmen die diese prozedur verwenden. |
Hast Du ev. vergessen den Anhang hochzuladen?
elundril - Do 29.03.07 23:44
ups stimmt! :oops: sry!
lg el
elundril - Di 22.05.07 10:44
keine Rückmeldungen? :-(
lg el
Christian S. - Mo 28.05.07 17:32
Hi!
Sorry, Lib-Beiträge zu prüfen ist deutlich aufwendiger als Forenbeiträge zu überfliegen. Da habe ich nicht immer Zeit für.
Jetzt aber:
Zuerst fällt mir auf, dass da try-finally fehlt. Du gibst zwar brav alles wieder frei, aber ein try-finally wäre da der Zuckerguss ;-)
Außerdem: Was passiert, wenn Image1 größer als Image2 ist? Wenn ich richtig sehe, greift man dann auf Speicher zu, von dem man die Finger lassen sollte.
Grüße
Christian
elundril - Mi 30.05.07 19:38
kann man mir mal helfen?
ich hab keine idee wie ich das überprüfen könnte. ich hab mir gedacht das ich vielleicht nachschauen kann ob im pointer was drin ist oder leer.
ne andere idee is halt das ich überprüf welches größer ist aber das würde den Quellcode ungemein vergrößern.
lg el
Christian S. - So 15.07.07 11:45
Also, zum einen schreibt man die "TIrgendwas.Create" immer vor das try und nicht mit rein.
Nun zu der Sache mit der Größe:
Du hast zwei Möglichkeiten
(1) Du kannst eine Exception werfen, wenn das erste Bild größer als das Zweite ist
(2) Du lässt die Schleifen jeweils bis zum Minimum der beiden Seitenlängen laufen
elundril - So 15.07.07 21:55
geht das jetzt so?? ich schau einfach ob in einem der zwei pointer nix drin steht. wenns so ist dann wird das ganze abgebochen.
Oder gibts ne bessere möglichkeit?
lg elundril
Christian S. - So 15.07.07 21:57
Ist denn sichergestellt, dass der Pointer dann nil ist? Oder kann auch nur "Unsinn" drin stehen, als was gerade an der Stelle im Speicher steht.
Außerdem: in der inneren Schleife kannst Du auch weiterhin "rauslaufen".
Wieso läufst Du nicht einfach bis zum Minimum der Seitenlängen?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| if image1.Height < image2.Height then minHeight := image1.Height else minHeight := image2.Height;
for y := 0 to minHeight-1 do ... |
elundril - So 15.07.07 22:01
:autsch: stimmt, stimmt, stimmt!
Jop is ne gute idee!
Gib mir noch ein paar tage zeit bitte und ich werd das ganze nochmal überarbeiten.
lg elundril
Christian S. - Mo 23.07.07 10:39
Baust Du die Änderungen noch ein? :-)
elundril - Mo 23.07.07 11:31
ja natürlich! ich hab nur vergessen wegen dem release von SpeedNotes! Sry!!
lg elundril
Christian S. - Mo 30.07.07 01:37
elundril hat folgendes geschrieben: |
ja natürlich! ich hab nur vergessen wegen dem release von SpeedNotes! |
Der Release muss echt anstrengend gewesen sein :mrgreen:
elundril - Mo 30.07.07 08:33
Christian S. hat folgendes geschrieben: |
elundril hat folgendes geschrieben: | ja natürlich! ich hab nur vergessen wegen dem release von SpeedNotes! | Der Release muss echt anstrengend gewesen sein :mrgreen: |
3 Versionen am ersten Tag sind nichts ungewöhnliches! Frag Microsoft! :lol:
lg elundril
Narses - Do 03.07.08 00:19
Moin!
Christian S. hat folgendes geschrieben: |
Außerdem: Was passiert, wenn Image1 größer als Image2 ist? Wenn ich richtig sehe, greift man dann auf Speicher zu, von dem man die Finger lassen sollte. |
Christian S. hat folgendes geschrieben: |
Wieso läufst Du nicht einfach bis zum Minimum der Seitenlängen?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| if image1.Height < image2.Height then minHeight := image1.Height else minHeight := image2.Height;
for y := 0 to minHeight-1 do ... | |
Leider tritt bei deinem Demo-Programm immer noch eine Exception auf, wenn Image1 größer als Image2 ist.
Christian S. hat dir doch bereits einen Vorschlag gemacht, wie du das Problem lösen kannst. :nixweiss:
Hast du überhaupt noch Interesse, den FAQ-Beitrag weiterzuentwickeln? ;)
cu
Narses
elundril - Do 03.07.08 02:13
jop, natürlich, sorry das ich da bis jetzt nichts gemacht habe, Schule ist in den letzten beiden Jahren etwas für mich vor gegangen und da hatte ich keine Zeit. Aber jetzt mit neuem Laptop und mehr Zeit mach ich mich wieder ans werk. danke fürs erinnern.
lg elundril
Tilman - Mi 23.07.08 00:14
Titel: Re: Alphablend zweier TGraphics
elundril hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| for x:= 0 to bmpImg1.width-1 do begin p1^[0] := ((p1^[0]*(AlphaValue+1)) + (p2^[0]*(256-AlphaValue))) shr 8); p1^[1] := ((p1^[1]*(AlphaValue+1)) + (p2^[1]*(256-AlphaValue))) shr 8); p1^[2] := ((p1^[2]*(AlphaValue+1)) + (p2^[2]*(256-AlphaValue))) shr 8); inc(p1); inc(p2); end; |
|
funzt nicht, habs mal so geändert, ist das richtig?
Delphi-Quelltext
1: 2: 3:
| p1^[0] := ((p1^[0]*(AlphaValue+1) + (p2^[0]*(256-AlphaValue))) shr 8); p1^[1] := ((p1^[1]*(AlphaValue+1) + (p2^[1]*(256-AlphaValue))) shr 8); p1^[2] := ((p1^[2]*(AlphaValue+1) + (p2^[2]*(256-AlphaValue))) shr 8); |
Ansonsten super Sache, genau das was ich gerade brauche =) hab allerdings die Parameter auf TBitmap geändert anstelle von TGraphic.
elundril - Do 24.07.08 14:56
Jop, is richtig so. Heut abend kommt dann eh eine neue Version mit den Bugfixes.
Freut mich das es dir hilft.
lg elundril
Narses - Mi 06.08.08 00:10
Moin!
Ein weiterer Monat ist seit meiner letzten Anfrage unwiederbringlich im Abgrund der Vergessenheit versunken... :)
elundril am Do 24.07.08 14:56 hat folgendes geschrieben: |
Heut abend kommt dann eh eine neue Version mit den Bugfixes. |
Wie sieht´s aus, kommst du voran? ;)
cu
Narses
Tilman - Mi 06.08.08 17:17
Hm, möglicherweise dachte eldunril ich sei ein Moderator oder Bibliothekar; natürlich meinte ich mit "ich habs mal so geändert" eigentlich "ich habs mal so geändert - in meinem Projekt". Da ist also noch was zu tun ;)
elundril - Do 07.08.08 13:11
es ist leider etwas dringendes dazwischen gekommen. (die entscheidung über meine zukunft aber ich bin noch am ball!)
lg elundril
Narses - Mo 15.12.08 16:23
Moin!
Wie sieht´s aus, speziell in den anstehenden Weihnachtsferien und mit diesem FAQ-Beitrag... :D
cu
Narses
Christian S. - So 08.02.09 13:05
Hallo!
Könntest Du diesem FAQ-Beitrag noch den letzten Schliff verpassen? :-)
Grüße
Christian
Narses - Mi 23.12.09 00:33
Moin!
Meinst du, du kriegst das hier noch jemals fertig? :| :nixweiss:
cu
Narses
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!