Drawalphaimage - Bilder mit Transparenzfaktor
Übersicht

![]() |
TritonBetreff: Drawalphaimage - Bilder mit Transparenzfaktor |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jo, folgende Funktion funktioniert im Grunde wie die normalen Befehle Drawimage und Drawblock, nur dass man noch einen Transparenzfaktor angeben kann. Eine nützliche Erweiterung für Blitz2D, das sowas von Haus aus nicht kann. Hatte sowas noch bei mir rumliegen, habs aber nochmal bischen ordentlicher neugeschrieben.
Die Geschwindigkeit ist vielleicht noch verbesserbar. Wer was findet, soll sich bemerkbar machen. Code: [AUSKLAPPEN] ;*** Zeichnet Bilder mit Transparenz ;*** 14.10.2005, by Triton, verbessert 18.08.2006 ;*** http://www.silizium-net.de Graphics 800,600,32,1 SetBuffer BackBuffer() HidePointer Global fpsrate,loops, fpstime Dim alphaimage(GraphicsWidth(),GraphicsHeight()) bild=LoadImage("bild.bmp") bg=LoadImage("texture1.jpg") Color 255,255,255 SetBuffer BackBuffer() While Not KeyDown(1) If MouseDown(1) Then a=a+5 If MouseDown(2) Then a=a-5 TileBlock(bg,0,0) Drawalphaimage(bild,MouseX(),MouseX(),a) Color 255,255,255 Plot MouseX(),MouseY() Text 10, 30, fps()+" FPS" If a < 0 Then a = 0 If a > 100 Then a = 100 Text 10,10, "Maustaste L/R zur Änderung der Deckung: "+a+"%" Flip Cls Wend ;--- Function fps() loops = loops+1 If MilliSecs() - fpstime > 1000 Then fpsrate = loops loops = 0 fpstime = MilliSecs() End If Return fpsrate End Function ;--- Function drawalphaimage(pic,x,y,a) ;** a=0(transparent)-100(deckend) ;** zeichnet jeden Pixel -> recht langsam If a <= 0 Then Return If a => 100 Then DrawBlock(pic,x,y) Return End If SetBuffer ImageBuffer(pic) ;einlesen des Bildes LockBuffer ImageBuffer(pic) For scanx = 0 To ImageWidth(pic)-1 For scany= 0 To ImageHeight(pic)-1 alphaimage(scanx,scany)=ReadPixelFast(scanx,scany) Next Next UnlockBuffer ImageBuffer(pic) SetBuffer BackBuffer() ; auslesen des Hintergrundes und LockBuffer BackBuffer() ; mischen und malen der neuen Pixel For scanx = 0 To ImageWidth(pic)-1 For scany= 0 To ImageHeight(pic)-1 rgb2=ReadPixelFast(scanx+x,scany+y) rbg=(rgb2 And $FF0000)/$10000 gbg=(rgb2 And $FF00)/$100 bbg=rgb2 And $FF rpic=(alphaimage(scanx,scany) And $FF0000)/$10000 gpic=(alphaimage(scanx,scany) And $FF00)/$100 bpic=alphaimage(scanx,scany) And $FF rneu=rbg*(1.0-(a/100.0))+rpic*a/100.0 gneu=gbg*(1.0-(a/100.0))+gpic*a/100.0 bneu=bbg*(1.0-(a/100.0))+bpic*a/100.0 rgbneu=255*$1000000 + rneu*$10000 + gneu*$100 + bneu WritePixelFast(scanx+x,scany+y,rgbneu) Next Next UnlockBuffer BackBuffer() End Function ;--- Function drawalphaimage2(pic,x,y,a) ;** a=0(transparent)-100(deckend) ;** zeichnet bei 0 < Transparenz < 100 nur alle 2 Pixel ;** -> 4x schneller If a <= 0 Then Return If a => 100 Then DrawBlock(pic,x,y) Return End If SetBuffer ImageBuffer(pic) ;einlesen des Bildes LockBuffer ImageBuffer(pic) For scanx = 0 To ImageWidth(pic)-1 Step 2 ;! For scany= 0 To ImageHeight(pic)-1 Step 2 ;! alphaimage(scanx,scany)=ReadPixelFast(scanx,scany) Next Next UnlockBuffer ImageBuffer(pic) SetBuffer BackBuffer() ; auslesen des Hintergrundes und LockBuffer BackBuffer() ; mischen und malen der neuen Pixel For scanx = 0 To ImageWidth(pic)-1 Step 2 ;! For scany= 0 To ImageHeight(pic)-1 Step 2 ;! rgb2=ReadPixelFast(scanx+x,scany+y) rbg=(rgb2 And $FF0000)/$10000 gbg=(rgb2 And $FF00)/$100 bbg=rgb2 And $FF rpic=(alphaimage(scanx,scany) And $FF0000)/$10000 gpic=(alphaimage(scanx,scany) And $FF00)/$100 bpic=alphaimage(scanx,scany) And $FF rneu=rbg*(1.0-(a/100.0))+rpic*a/100.0 gneu=gbg*(1.0-(a/100.0))+gpic*a/100.0 bneu=bbg*(1.0-(a/100.0))+bpic*a/100.0 rgbneu=255*$1000000 + rneu*$10000 + gneu*$100 + bneu WritePixelFast(scanx+x,scany+y,rgbneu) WritePixelFast(scanx+x+1,scany+y,rgbneu) ;! WritePixelFast(scanx+x,scany+y+1,rgbneu) ;! WritePixelFast(scanx+x+1,scany+y+1,rgbneu) ;! Next Next UnlockBuffer BackBuffer() End Function |
||
Coding: silizium-net.de | Portfolio: Triton.ch.vu |
- Zuletzt bearbeitet von Triton am Do, Nov 02, 2006 17:15, insgesamt 2-mal bearbeitet
![]() |
Hummelpups |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hm, nett, nur obs dann auch für einem komplexes Spiel
schnell genug ist... Ich weiß es nicht, hab es nicht getestet ![]() IMurDOOM |
||
blucode - webdesign - Ressource - NetzwerkSim
BlitzBasic 2D - BlitzMax - MaxGUI - Monkey - BlitzPlus |
CodeMaster |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Darf ich fragen, warum du jeweils pro Aufruf den Buffer auf das Image stellst, das Bild per (Speedbremse) Readpixelfast in das Array lädst, den Buffer wieder zurückstellst, den Buffer wieder einfrierst, das Array durchgehst, die Punkte setzt und am Ende den Buffer wieder freigibst? Warum so kompliziert?
Mach doch ne Funktion z.B. namens LoadAlphaImage, die eine Bank mit den Pixelwerten des zu zeichnenden Bildes erstellt. In der Funktion DrawAlphaImage brauchst du dann die jeweiligen Bilder nicht mehr pixelweise einzulesen, was einen enormen Geschwindigkeitsvorteil bringen sollte. |
||
Dies ist ein Text, der an jeden Beitrag von dir angehängt werden kann. Es besteht eine Limit von 500 Buchstaben.
Zuletzt bearbeitet von CodeMaster am Mo Apr 01, Parse error: syntax error, unexpected ';' in htdocs\viewtopic.php on line 102 |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi!
Find ich klasse, wäre auch toll, wenn du noch weiter dran arbeiten würdest ![]() btw: an welche, die gerade keine Bilder da haben, wie ich ![]() ersetzt: Code: [AUSKLAPPEN] bild=LoadImage("sweet.jpg")
bg=LoadImage("sunrise1.jpg") durch: Code: [AUSKLAPPEN] Dim alphaimage(grafikx,grafiky)
bild=CreateImage(100,100) SetBuffer ImageBuffer(bild) Color 255,0,0 Rect 0,0,100,100 bg=CreateImage(300,300) SetBuffer ImageBuffer(bg) Color 0,0,255 Rect 10,10,300,300 Color 255,255,255 SetBuffer BackBuffer() ist zwar bestimmt nicht so effektvoll, aber naja ![]() ![]() MfG #Reaper |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Darf ich fragen, warum du [...]
Damits sich der Befehl exakt wie Drawimage und Drawblock verhält. Freilich habe ich das bei jedem Aufruf unnötig verlangsamende neueinlesen des Bildes erkannt, aber das muss so, wenn man nicht nur ein und immer das gleiche Bild so zeichnet, sondern viele verschiedene. Zitat: Mach doch ne Funktion z.B. namens LoadAlphaImage, die eine Bank mit den Pixelwerten des zu zeichnenden Bildes erstellt. In der Funktion DrawAlphaImage brauchst du dann die jeweiligen Bilder nicht mehr pixelweise einzulesen, was einen enormen Geschwindigkeitsvorteil bringen sollte.
hmjo, könnte man machen. |
||
Coding: silizium-net.de | Portfolio: Triton.ch.vu |
CodeMaster |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hier also mal die (in der Eile gecodete) Bank-Variante:BlitzBasic: [AUSKLAPPEN] Graphics 800,600(Maskcolor ist noch nicht implementiert, ist aber nicht sonderlich aufwendig) Triton hat Folgendes geschrieben: Damits sich der Befehl exakt wie Drawimage und Drawblock verhält. Nun ja, das Spielchen könnte man jetzt noch ins Extreme weiterführen und die Bilder nicht als Bank sondern als Type "TBitmap" (welche sowohl Originalbild als auch Bitmap-Bank speichert) zurückgeben und anschließend die Befehle DrawImage und DrawBlock überladen, sodass man jeweils das Type als Parameter übergibt und anhand des Transparentwertes (a = 255) entweder das Originalbild mit dem Originalbefehl DrawImage/-Block oder die Bitmap-Bank mit der Alphaberechnungsprozedur verwendet wird. Das wäre im Grund aber wirklich nur ne Spielerei...
|
||
Dies ist ein Text, der an jeden Beitrag von dir angehängt werden kann. Es besteht eine Limit von 500 Buchstaben.
Zuletzt bearbeitet von CodeMaster am Mo Apr 01, Parse error: syntax error, unexpected ';' in htdocs\viewtopic.php on line 102 |
- Zuletzt bearbeitet von CodeMaster am So, Okt 16, 2005 11:15, insgesamt einmal bearbeitet
![]() |
Triton |
![]() Antworten mit Zitat ![]() |
---|---|---|
Gut. Sowas nennt man Eigeninitiative - sollten wir öfters haben. | ||
Coding: silizium-net.de | Portfolio: Triton.ch.vu |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also an der speed sollte man vielleicht doch etwas tuen.. ![]() CodeMaster's code braucht bei fullscreen und einem 1024x768 großem screen ca. ~770ms für einen aufbau.. ![]() ![]() Naja... B3D ist halt nicht dafür gedacht ![]() MfG #Reaper |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
Jean |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo
Ich habe die Funktion mal so abgeändert, dass eine transparente Hintergrundfarbe unterstützt wird: Code: [AUSKLAPPEN] Graphics 800,600 SetBuffer BackBuffer() Dim alphaimage(GraphicsWidth (),GraphicsHeight ()) ;Array wird in der Funktion benötigt! bild=LoadImage("janware.bmp") bg=LoadImage("hin.bmp") While Not KeyDown(1) DrawBlock(bg,0,0) drawalphaimage(bild,MouseX(),MouseY(),50,0,0,0) Flip Cls Wend Function drawalphaimage(pic,x,y,a,mask_r,mask_g,mask_b) ;a=0(transp)-100(deckend),mask_x=Farbmaske If a <= 0 Then Return SetBuffer ImageBuffer(pic) ;einlesen des Bildes LockBuffer ImageBuffer(pic) For scanx = 0 To ImageWidth(pic)-1 For scany= 0 To ImageHeight(pic)-1 alphaimage(scanx,scany)=ReadPixelFast(scanx,scany) Next Next UnlockBuffer ImageBuffer(pic) SetBuffer BackBuffer() ; auslesen des Hintergrundes und LockBuffer BackBuffer() ; mischen und malen der neuen Pixel For scanx = 0 To ImageWidth(pic)-1 For scany= 0 To ImageHeight(pic)-1 rgb2=ReadPixelFast(scanx+x,scany+y) rbg=(rgb2 And $FF0000)/$10000 gbg=(rgb2 And $FF00)/$100 bbg=rgb2 And $FF rpic=(alphaimage(scanx,scany) And $FF0000)/$10000 gpic=(alphaimage(scanx,scany) And $FF00)/$100 bpic=alphaimage(scanx,scany) And $FF If Not rpic = mask_r And gpic = mask_g And bpic = mask_b rneu=rbg*(1.0-(a/100.0))+rpic*a/100.0 gneu=gbg*(1.0-(a/100.0))+gpic*a/100.0 bneu=bbg*(1.0-(a/100.0))+bpic*a/100.0 rgbneu=255*$1000000 + rneu*$10000 + gneu*$100 + bneu WritePixelFast(scanx+x,scany+y,rgbneu) EndIf Next Next UnlockBuffer BackBuffer() End Function |
||
$tankY |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
da isn kleiner bug, das array geht so weit wie bei graphics definiert, was ist, wenn jedoch das bild größer is ![]() Code: [AUSKLAPPEN] Graphics 800,600 SetBuffer BackBuffer() Dim alphaimage(GraphicsWidth (),GraphicsHeight ()) ;Array wird in der Funktion benötigt! bild=LoadImage(file1$);File1 und file2 muss vorher definiert werden bg=LoadImage(file2$) While Not KeyDown(1) DrawBlock(bg,0,0) drawalphaimage(bild,MouseX(),MouseY(),50,0,0,0) Flip Cls Wend Function drawalphaimage(pic,x,y,a,mask_r,mask_g,mask_b) ;a=0(transp)-100(deckend),mask_x=Farbmaske If a <= 0 Then Return SetBuffer ImageBuffer(pic) ;einlesen des Bildes LockBuffer ImageBuffer(pic) For scanx = 0 To GraphicsWidth ()-1 For scany= 0 To GraphicsHeight ()-1 alphaimage(scanx,scany)=ReadPixelFast(scanx,scany) Next Next UnlockBuffer ImageBuffer(pic) SetBuffer BackBuffer() ; auslesen des Hintergrundes und LockBuffer BackBuffer() ; mischen und malen der neuen Pixel For scanx = 0 To GraphicsWidth ()-1 For scany= 0 To GraphicsHeight ()-1 rgb2=ReadPixelFast(scanx+x,scany+y) rbg=(rgb2 And $FF0000)/$10000 gbg=(rgb2 And $FF00)/$100 bbg=rgb2 And $FF rpic=(alphaimage(scanx,scany) And $FF0000)/$10000 gpic=(alphaimage(scanx,scany) And $FF00)/$100 bpic=alphaimage(scanx,scany) And $FF If Not rpic = mask_r And gpic = mask_g And bpic = mask_b rneu=rbg*(1.0-(a/100.0))+rpic*a/100.0 gneu=gbg*(1.0-(a/100.0))+gpic*a/100.0 bneu=bbg*(1.0-(a/100.0))+bpic*a/100.0 rgbneu=255*$1000000 + rneu*$10000 + gneu*$100 + bneu WritePixelFast(scanx+x,scany+y,rgbneu) EndIf Next Next UnlockBuffer BackBuffer() End Function aber irgendwie funzt das bei mir (bb+) nicht ![]() |
||
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@stanky: irgendwie geht deines nicht richtig, habe allerdings die LoadImage durch Createimage ersetzt... :-/
@Triton: da fällt mir gerade auf, was sehr seltsammes: wenn ich mit dem tranparenten bild an der seite drüber hinausgehe, taucht ein stück des bildes wieder auf der gegenüberliegenden seite auf, naja, ist ja nicht so schlimm, aber wenn ich das transparente bild über den unteren rand zeichnen lasse, taucht davon oben wieder was auf, allerdings nicht als ganzes, sondern irgendwie nur ein paar pixel davon, sehr seltsam... dieser Bug ist mir auchschonmal bei aMul's Demo (im WiP) mit dem Sand, oder was das war, aufgefallen... :-/ Die (bei mir roten punkte und rechtecke) gehen dann nichtmal mit Cls weg :O |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
miLORD |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ Stanky: Bei mir funktioniert deins auch nicht richtig...
@ All Ich hab Jeans version verbessert, nun zeigt er keinen Fehler mehr an, wenn das bild über den Rand hinaus geht, also kommt es auch auf der anderen seite nicht mehr raus. Code: [AUSKLAPPEN] Graphics 1024,768
SetBuffer BackBuffer() Dim alphaimage(GraphicsWidth (),GraphicsHeight ()) ;Array wird in der Funktion benötigt! bild=LoadImage() bg=LoadImage() While Not KeyDown(1) DrawBlock(bg,0,0) my = MouseY() mx = MouseX() drawalphaimage(bild,mx,my,50,0,0,0) Flip Cls Wend Function drawalphaimage(pic,x,y,a,mask_r,mask_g,mask_b) ;a=0(transp)-100(deckend),mask_x=Farbmaske If a <= 0 Then Return SetBuffer ImageBuffer(pic) ;einlesen des Bildes LockBuffer ImageBuffer(pic) For scanx = 0 To ImageWidth(pic)-1 For scany= 0 To ImageHeight(pic)-1 alphaimage(scanx,scany)=ReadPixelFast(scanx,scany) Next Next UnlockBuffer ImageBuffer(pic) SetBuffer BackBuffer() ; auslesen des Hintergrundes und LockBuffer BackBuffer() ; mischen und malen der neuen Pixel For scanx = 0 To ImageWidth(pic)-1 For scany= 0 To ImageHeight(pic)-1 If Not ((scanx+x >= GraphicsWidth()) Or (scany+y >= GraphicsHeight())) Then rgb2=ReadPixelFast(scanx+x,scany+y) rbg=(rgb2 And $FF0000)/$10000 gbg=(rgb2 And $FF00)/$100 bbg=rgb2 And $FF rpic=(alphaimage(scanx,scany) And $FF0000)/$10000 gpic=(alphaimage(scanx,scany) And $FF00)/$100 bpic=alphaimage(scanx,scany) And $FF If Not rpic = mask_r And gpic = mask_g And bpic = mask_b rneu=rbg*(1.0-(a/100.0))+rpic*a/100.0 gneu=gbg*(1.0-(a/100.0))+gpic*a/100.0 bneu=bbg*(1.0-(a/100.0))+bpic*a/100.0 rgbneu=255*$1000000 + rneu*$10000 + gneu*$100 + bneu WritePixelFast(scanx+x,scany+y,rgbneu) EndIf EndIf Next Next UnlockBuffer BackBuffer() End Function |
||
brqwq?! oO |
$tankY |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@miLORD und #Reaper:
Das Problem ist, dass nicht nur mein Code nicht funktioniert, sondern auch der Code von Triton (zumindest bei mir auf B+ v1.42). Deshalb habe ich das mit dem Array probiert, da zuerst da der Fehler lag (wenn BildBreite > DimBreite). Aber wenn das Dim so groß ist wie das Bild, stürtzt er einfach ab, ohne eine Fehlermeldung im Debugger. €dit: Dein Code funktioniert nun bei mir! |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group