TPixmap grabben mit Alphachannel

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Firstdeathmaker

Betreff: TPixmap grabben mit Alphachannel

BeitragDi, Feb 26, 2008 14:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Folgendes Problem:

Ich will Ingame dynamisch Buttons erstellen.

Gegeben: Standartbuttonimage (PNG mit Alphachannel), Font:TImageFont, Text:String

Problem: Grabimage funktioniert allem Anschein nach nicht richtig. Und selbst wenn, wie kriege ich Alphachannelinformationen in das neue Bild ausgehend vom alten und dem Textstring?

Code: [AUSKLAPPEN]
Function RenderButton:TImage(button:TImage,font:TImageFont,text:String)
   Cls
   DrawImage button,0,0
   SetColor 0,0,0
   DrawText text,(ImageWidth(button)-TextWidth(text))/2,(ImageHeight(button)-TextHeight(text))/2


   '1. Version: Fehlerhaft
   Local image:TImage = CreateImage(ImageWidth(button),ImageHeight(button),1,DYNAMICIMAGE|MASKEDIMAGE|FILTEREDIMAGE)
   GrabImage image,0,0
   Cls
   Return image
End Function
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image
 

ChristianK

BeitragDi, Feb 26, 2008 15:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ein Bild gerendert wird, dann werden die Alphawerte mit den darunter liegenden Pixeln ( im Normalfall schwarz ) kombiniert, somit geht der Alphachannel des Bildes "verloren". Deshalb glaub ich nicht, dass GrabImage nen Fehler hat.
Vielleicht könntest du das mit Render-to-Texture lösen oder, etwas umständlicher und langsamer, über Pixmaps ( die Freetype-Glyphs mit WritePixel in das Bild kopieren ).
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT

Firstdeathmaker

BeitragDi, Feb 26, 2008 16:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist mir schon klar, dass die Alphainformationen bei Grabimage nicht übertragen werden können. Aber der Fehler den mein Code da oben produziert äußert sich in einer totalen Zerstörung des Bildes (in komische Blöcke).

Naja, ich werds mal mit Pixmaps lösen, indem ich mir die passenden Bilder von TImageFont rauskrame und mit Readpixel und Writepixel direkt übertrage.
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image
 

Dreamora

BeitragDi, Feb 26, 2008 18:12
Antworten mit Zitat
Benutzer-Profile anzeigen
button hat 2er potenz seitenlängen?
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Firstdeathmaker

BeitragDi, Feb 26, 2008 18:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie kommst du denn darauf?
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image
 

ChristianK

BeitragDi, Feb 26, 2008 18:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Dreamora,
hat er mit Sicherheit, weil die Textur beim Laden immer auf einen ^2-Wert angepasst wird.
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT

Firstdeathmaker

BeitragDi, Feb 26, 2008 19:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habs jetzt schon fast, aber irgendwie machen mir ein paar Rundungsfehler das Leben schwer. Es treten jedenfalls Grafikfehler auf und ich weis nicht warum.

Wie es funktionieren sollte:
Das Buchstabenimage soll über den Button eingezeichnet werden, ohne dabei weniger transparent zu sein als der Button darunter. Falls der Pixel des Buchstabens dabei selber transparent ist, soll als Farbwert der entsprechende Anteil vom Buchstaben mit dem gegenteiligen Farbanteil des Bildes vermischt werden.

Code: [AUSKLAPPEN]
Function RenderButton:TImage(button:TImage,font:TImageFont,text:String)
   SetImageFont font
   Rem
   Cls
   DrawImage button,0,0
   SetColor 0,0,0
   DrawText text,(ImageWidth(button)-TextWidth(text))/2,(ImageHeight(button)-TextHeight(text))/2
   End Rem
   Local map:TPixmap = LockImage(button)
   
   Local textposx:Int = (button.width - TextWidth(text))/2
   Local textposy:Int = (button.height - TextHeight(text))/2
   Local x:Int
   
   For Local i:Int = 0 Until text.length
      Local n:Int = font.CharToGlyph(text[i])
      If n<0 Continue
      
      Local glyph:TImageGlyph=font.LoadGlyph(n)
      Local image:TImage=glyph._image
         
      If image
         Local frame:TImageFrame=image.Frame(0)
         If frame      
            'frame.Draw 0,0,image.width,image.height,x+tx,y+ty
            'Auf den eigendlichen Button rendern
            Local map2:TPixmap = LockImage(image,0,1,0)
            For Local x0:Int=0 Until image.width
            For Local x1:Int=0 Until image.height
               Local c1:Int = ReadPixel(map2,x0,x1)
               Local c2:Int = ReadPixel(map,x0+x+textposx,x1+textposy)

               Local a1:Int=c1 Shr 24
               Local rgb1:Int = (c1 Shl 8) Shr 8
               
               Local a2:Int=c2 Shr 24
               Local rgb2:Int= (c2 Shl 8) Shr 8


               DebugLog "argb1: "+ PrintARGB(c1)
               DebugLog "argb2: "+ PrintARGB(c2)
               

               rgb1 = (((a1) * rgb1)) /$FF'Shr 8
               rgb2 = (((255 - a1) * rgb2)) /$FF'Shr 8

               
               Local c3:Int = (a2*$1000000) + rgb1 + rgb2
               
               DebugLog "argb3: "+ PrintARGB(c3)
               DebugLog "___"
               
               WritePixel(map,x0+x+textposx,x1+textposy,c3)
            Next
            Next
            UnlockImage(image)
         EndIf
         x:+glyph.Advance()
      EndIf
   Next

   Rem
   '1. Version: Fehlerhaft
   Local image:TImage = CreateImage(ImageWidth(button),ImageHeight(button),1,DYNAMICIMAGE|MASKEDIMAGE|FILTEREDIMAGE)
   GrabImage image,0,0
   Cls
   End Rem
   
   UnlockImage button
   Return button
End Function

Function PrintARGB:String(c:Int)
   Local a:Int=(c Shr 24)
   Local r:Int=((c Shl 8) Shr 8)/$10000
   Local g:Int=((c Shl 16) Shr 16)/$100
   Local b:Int=((c Shl 24) Shr 24)
    Return a+","+r+","+g+","+b+"   "+Bin(c)
End Function



EDIT: Hab die Rundungsfehler heraus bekommen und es funktioniert einwandfrei. Nur die Buchstaben werden noch etwas falsch positioniert, aber da muss ich nochmal im ImageFont nachschauen.

Code: [AUSKLAPPEN]
Function RenderButton:TImage(button:TImage,font:TImageFont,text:String)
   SetImageFont font
   Local map:TPixmap = LockImage(button)
   
   Local textposx:Int = (button.width - TextWidth(text))/2
   Local textposy:Int = (button.height - TextHeight(text))/2
   Local x:Int
   
   For Local i:Int = 0 Until text.length
      Local n:Int = font.CharToGlyph(text[i])
      If n<0 Continue
      
      Local glyph:TImageGlyph=font.LoadGlyph(n)
      Local image:TImage=glyph._image
         
      If image
         Local frame:TImageFrame=image.Frame(0)
         If frame      
            'frame.Draw 0,0,image.width,image.height,x+tx,y+ty
            'Auf den eigendlichen Button rendern
            Local map2:TPixmap = LockImage(image,0,1,0)
            For Local x0:Int=0 Until image.width
            For Local x1:Int=0 Until image.height
            
               Local px0:Int = x0+x+textposx
               Local px1:Int = x1+textposy
               
               If px0>0 And px1>0 And px0<button.width And px1<button.height 'Secure against buffer overrun
                  Local c1:Int = ReadPixel(map2,x0,x1)
                  Local c2:Int = ReadPixel(map,x0+x+textposx,x1+textposy)
   
                  Local a1:Int=c1 Shr 24
                  Local rgb1:Long = (c1 Shl 8) Shr 8
                  
                  Local a2:Int=c2 Shr 24
                  Local rgb2:Long= (c2 Shl 8) Shr 8
   
                  Local r1:Int=((c1 Shl 8) Shr 8)/$10000
                  Local g1:Int=((c1 Shl 16) Shr 16)/$100
                  Local b1:Int=((c1 Shl 24) Shr 24)
         
                  Local r2:Int=((c2 Shl 8) Shr 8)/$10000
                  Local g2:Int=((c2 Shl 16) Shr 16)/$100
                  Local b2:Int=((c2 Shl 24) Shr 24)
                  
                  Local r3:Int=((a1*r1) + (255-a1)*r2)/255
                  Local g3:Int=((a1*g1) + (255-a1)*g2)/255
                  Local b3:Int=((a1*b1) + (255-a1)*b2)/255
                  
                  Local c3:Int = a2*$1000000 + r3*$10000 + g3*$100 + b3
               
                  WritePixel(map,x0+x+textposx,x1+textposy,c3)
               EndIf
            Next
            Next
            UnlockImage(image)
         EndIf
         x:+glyph.Advance()
      EndIf
   Next
   
   UnlockImage button
   Return button
End Function
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group