Page 1 of 1

Alpha Blended Image

Posted: Tue Aug 28, 2007 11:23 pm
by Dibalo
Eli Niko40 tässä joskus ajat sitten minulle ilmoitteli tekevänsä omaa alpha blending -systeemiä, jossa kuvia voi blendata portaattomasti (siis monta eri alpha-arvoa samassa kuvassa eri kohdissa kuvaa). Noh... pohdimme, että miten saisimme pistää systeemin toimimaan ennestään olevilla kuvaformaateilla. Kävimme tonkimaan eri formaattien pakkaus-algoritmejä sekä rakenteita. Totesimme sen ne liian monimutkaisiksi, joten intoni lopahti siihen ja annoin asian olla.

Mutta sitten Niko taas laittoi koodia minulle ja kyseli, että miksi ei toimi. Muuttujat olivat sellaisia, että en tajunnut koodista mitään. Sain kuitenkin Nikolta blendaukseen tarvittavan koodin (pikselimanipulaation) sekä idean kahdesta kuvasta. En kuitenkaan pitänyt Nikon (mielestäni) tökeröstä tavasta tallentaa alpha blendattu kuva käsittelyn jälkeen ja ladata se uudestaan (ainakin näin koodin tulkitsin). Mutta nyt kaikki ideat oli kasassa, ja siitä se ajatus sitten lähti! :D

Eli tekemäni kaksi funktiota mahdollistavat portaattoman alpha blendauksen. Siihen tarvitaan kaksi kuvaa: blendattava, aivan tavallinen kuva SEKÄ mustavalkoinen blendattavan kuvan kokoinen alpha-arvot sisältävä kuva. Tässä "alpha-kuvassa" musta on täysin läpinäkyvä ja valkoinen on täysin näkyvä pikseli. Seuraavassa funtioiden esittelyt:

Code: Select all

// lataa alpha blendattavan kuvan muistiin ja palauttaa osoittiminen kuvamuuttujaan
' image = luodun alpha blendatun kuvan indeksi
' imagePath$ = blendattavan kuvan polku
' alphaPath$ = alpha-kanavat sisältävän kuvan polku

image = LoadABImage(imagePath$, alphaPath$)



// piirtää muistiin ladatun blendattavan kuvan haluttuihin koordinaatteihin
' img = piirrettävä kuva, ladattu funktiolla "LoadABImage"
' x = x-koordinaatti näytöllä
' y = y-koordinaatti näytöllä

DrawABImage(img, x, y)



// luo muistiin uuden alpha blendatun imagen jo ohjelmaan ladatuista TAVALLISISTA kuvista (eli ei siis ab-kuvista)
' sImg = alpha blendattava kuva
' aImg = alpha-kanavan sisältävä kuva
img = MakeABImage(sImg, aImg)


// palauttaa AB-kuvan (HUOM! vain AB-kuva) leveyden
ABImageWidth(img)


// palauttaa AB-kuvan (HUOM! vain AB-kuva) korkeuden
ABImageHeight(img)
Seuraavassa itse rajapinnan koodi:

Code: Select all

// *********************** AlphaBlended Image ******************************
// *********************** (c) Matti 'Dibalo' Lankinen *********************



Const cMAX_AB_DATA = 400000             // maksimimäärä pikseleitä, joihin voidaan ladata alpha-tietoa
Const cMAX_AB_IMAGES = 100             // maksimimäärä alpha-blendattuja kuvia




// kuvien data taulukossa (1-3 = RGB, 0 = alpha)
Dim AB_IMAGE_DATA(cMAX_AB_DATA, 3) As Byte 
// datan sijainti kuvassa (0 = x, 1 = y)
Dim AB_IMAGE_DATA_POS(cMAX_AB_DATA,1) As Short 


// tärkeät tiedot AB-kuvista, luetaan indeksiluvulla
// jonka LoadABImage() luo
    ' 0 = sijainti IMAGE_DATASSA
    ' 1 = pointteri non-alpha kuvaan
    ' 2 = kuvan koko
Dim AB_IMAGE_INFO(cMAX_AB_IMAGES,2)



Global pImageCount              // laskuri kuinka monta alpha-kuvaa on luotu
Global imageDataPointer         // laskuri missä kohtaa on viimeinen kirjoitettu alpha-kuvan data


pImageCount         = 0
imageDataPointer    = 0







//////////////////////////////////////////////////////////////////


Function LoadABImage(imagePath$, alphaPath$)

    
    sImg = LoadImage(imagePath)         // stantardi image (ilman a-kanavaa)
    aImg = LoadImage(alphaPath)         // kuva, joka sisältää a-kanavan (mustavalkoinen)
    
    iW = ImageWidth(sImg)
    iH = ImageHeight(sImg)
    
    // tarkistetaan, onko alpha blendaus mahdollista
    If ImageWidth(aImg) <> iW Or ImageHeight(aImg) <> iH Then MakeError "Image sizes don´t match!"

    AB_IMAGE_INFO(pImageCount,0) = imageDataPointer
    AB_IMAGE_INFO(pImageCount,1) = sImg
    
    
    pCount = 0
    

    For x = 0 To iW-1
    For y = 0 To iH-1
        
        Lock Image(sImg)
            p1  = GetPixel2(x, y, Image(sImg))
        Unlock Image(sImg)
        Lock Image(aImg)
            a   = ((GetPixel2(x, y, Image(aImg)) Shl 8) Shr 24)
        Unlock Image(aImg)
        
        p1R = ((p1 Shl 8) Shr 24)
        p1G = ((p1 Shl 16) Shr 24)
        p1B = ((p1 Shl 24) Shr 24)
        

        
        If p1R Or p1G Or p1B Then
              
           Lock Image(sImg)
           
           If a And a <> 255 Then 
                
                AB_IMAGE_DATA(imageDataPointer, 0) = a
                AB_IMAGE_DATA(imageDataPointer, 1) = p1R
                AB_IMAGE_DATA(imageDataPointer, 2) = p1G
                AB_IMAGE_DATA(imageDataPointer, 3) = p1B
        
                AB_IMAGE_DATA_POS(imageDataPointer, 0) = x
                AB_IMAGE_DATA_POS(imageDataPointer, 1) = y
        
                pCount+1
                imageDataPointer+1

                PutPixel2 x, y, (0 + (0 Shl 8) + (0 Shl 16) + (255 Shl 24)), Image(sImg)
                
            EndIf 
            
            If a = 0 Then PutPixel x, y, (0 + (0 Shl 8) + (0 Shl 16) + (255 Shl 24)), Image(sImg)
        
            Unlock Image(sImg)
        
        EndIf 
        
    Next y
    Next x

    AB_IMAGE_INFO(pImageCount,2) = pCount
    pImageCount+1

    DeleteImage aImg
    Return (pImageCount-1)
    

End Function 



///////////////////////////////////////////


Function DrawABImage(img, x, y)

    DrawImage AB_IMAGE_INFO(img, 1), x, y

    sW = ScreenWidth()
    sH = ScreenHeight()

    Lock SCREEN()
        For i = AB_IMAGE_INFO(img,0) To AB_IMAGE_INFO(img,0)+AB_IMAGE_INFO(img,2)
            
            xx = AB_IMAGE_DATA_POS(i,0)+x
            yy = AB_IMAGE_DATA_POS(i,1)+y
            If 0 =< xx And xx <= sW And 0 <= yy And yy <= sH Then 
                p = GetPixel2( xx, yy)
            
                pros# = AB_IMAGE_DATA(i,0) / 255.0
                bR = ((p Shl 8) Shr 24)
                bG = ((p Shl 16) Shr 24)
                bB = ((p Shl 24) Shr 24)
            
                PutPixel2 xx, yy, (Int(bB+((AB_IMAGE_DATA(i,3)-bB)*pros)) + (Int(bG+((AB_IMAGE_DATA(i,2)-bG)*pros)) Shl 8) + (Int(bR+((AB_IMAGE_DATA(i,1)-bR)*pros)) Shl 16) + (255 Shl 24))
            EndIf 
          
        Next i  
    Unlock SCREEN()
    

End Function 

Ja sitten pieni esimerkkikoodi. Muistattehan ladata alla olevat mediat. ;)
Image Image

Code: Select all

SCREEN 640,480,0
Include "ABImage.cb"

ClsColor 255,255,255
Cls 

img = LoadABImage("face_original.png", "face_alpha.png")

Repeat
    DrawABImage(img, MouseX(), MouseY())
DrawScreen
Forever
Teho ei ole suurilla kuvilla hyvä, mutta pienille kuville funktiot ovat käyttökelposia.

Re: Alpha Blended Image

Posted: Wed Aug 29, 2007 8:10 am
by Jare
Kuulostaa hyvältä.

Mitäkähän onnistuin tekemään väärin kun ajaessani koodin esimerkkiohjelman kanssa niin ohjelma kaatuu virheilmoitukseen "Illegal instruction" ja sen jälkeen tulee vielä MAV? :shock:

CB bugaa?

Edit: En minäkään ole kuullut "Illegal instruction" -virheilmoituksesta aiemmin mitään. Pitää koettaa tätä uudestaan taas paremmalla ajalla.

Re: Alpha Blended Image

Posted: Wed Aug 29, 2007 10:27 am
by Dibalo
Jare wrote:Kuulostaa hyvältä.

Mitäkähän onnistuin tekemään väärin kun ajaessani koodin esimerkkiohjelman kanssa niin ohjelma kaatuu virheilmoitukseen "Illegal instruction" ja sen jälkeen tulee vielä MAV? :shock:
Jaa-a.... En ole koskaan kuullutkaan moisesta.... :shock:

Re: Alpha Blended Image

Posted: Thu Aug 30, 2007 9:15 am
by Nucreal
Dibalo wrote:
Jare wrote:Kuulostaa hyvältä.

Mitäkähän onnistuin tekemään väärin kun ajaessani koodin esimerkkiohjelman kanssa niin ohjelma kaatuu virheilmoitukseen "Illegal instruction" ja sen jälkeen tulee vielä MAV? :shock:
Jaa-a.... En ole koskaan kuullutkaan moisesta.... :shock:
Hehe, ihme juttu. Itselläni toimi, täydellisesti. ;D

Re: Alpha Blended Image

Posted: Tue Sep 04, 2007 4:26 pm
by tuhoojabotti
mullla se avasi ikkunan ja muutti sen koon ja sitten se sammu...

4.10.2007
nyt ku yritin -> MAV

Re: Alpha Blended Image

Posted: Mon Oct 15, 2007 5:16 pm
by elmo123
Vau! tuo on pakko lisätä SDK:hon! :D Kun käytän tuota aaltokuvan kanssa saan hienon liekin :mrgreen:
EDIT:

Olette varmaan nähneet Flash-peleissä pientä "laadunparannusta".
Tällä kun tekee vaikka pallokuvan ja alphakuvaan pistää pallon ihan rajalle puolinäkyvän värin niin pieni laadunparannushan se siinä :D


Re: Alpha Blended Image

Posted: Tue Oct 16, 2007 11:00 pm
by MaGetzUb
En yritä olla mikään expertti, mutta mulle tulee usein tuo "Illegal instruction", koska for...next silmukan sisällä on jotain desimaali sysäksiä. Sitte se kaatuu kun yritetään lukea jotain desimaali lukua kokonais lukuna... se on minun käsitykseni. Olen aika moinen säätäjä. :?

Re: Alpha Blended Image

Posted: Wed Oct 17, 2007 7:17 pm
by Dibalo
programmer of DSG wrote:En yritä olla mikään expertti, mutta mulle tulee usein tuo "Illegal instruction", koska for...next silmukan sisällä on jotain desimaali sysäksiä. Sitte se kaatuu kun yritetään lukea jotain desimaali lukua kokonais lukuna... se on minun käsitykseni. Olen aika moinen säätäjä. :?
Desimaaliluvut muutetaan varmasti kokonaisluvuiksi ennen käyttöä, joten arvauksesi on väärä.

Re: Alpha Blended Image

Posted: Thu Oct 18, 2007 12:58 am
by MaGetzUb
programmer of DSG wrote:En yritä olla mikään expertti, mutta mulle tulee usein tuo "Illegal instruction", koska for...next silmukan sisällä on jotain desimaali sysäksiä. Sitte se kaatuu kun yritetään lukea jotain desimaali lukua kokonais lukuna... se on minun käsitykseni. Olen aika moinen säätäjä. :?
EDIT:

Mutta minulla se tulee For- silmukan yhteydessä usein.