Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: [VB6] Pieni ExtFloodFill-ongelma

Sivun loppuun

vesimies [16.10.2007 15:07:45]

#

Moi!

Olen maalaillut alueita Api-funktiolla ExtFloodFill. Käytän valintaa FLOODFILLSURFACE, jolloin maalattava alue määräytyy sen mukaan kuinka kauan annettua väriä tulee vastaan, ts. alueen reuna voi tässä olla monivärinen.

Ongelma on nyt siinä, että funktio näkyy toimivan vain sellaisilla väreillä joiden R-, G- ja B-arvot loppuvat nollaan! Siis nimenomaan se on kranttu sen vanhan värin suhteen, ei sen maalausvärin.

Mikä nyt avuksi jotta saisi käytettyä kaikkia taustavärejä eikä tarvitsisi niitä lähteä pyöristelemään?

Antti Laaksonen [16.10.2007 16:41:34]

#

Vaikea sanoa näkemättä koodia, mutta seuraava ainakin toimii:

Private Sub Form_Load()
    ScaleMode = vbPixels
    Me.Show
    ' piirretään täytetty violetti neliö
    Line (50, 50)-(100, 100), RGB(133, 29, 203), BF
    ' piirretään sille turkoosi kehys
    Line (50, 50)-(100, 100), RGB(57, 238, 155), B
    ' valitaan täyttöväriksi punainen
    Me.FillColor = RGB(205, 49, 35)
    Me.FillStyle = vbSolid
    ' täytetään kuvion keskeltä reunoihin asti
    ExtFloodFill Me.hdc, 75, 75, RGB(133, 29, 203), FLOODFILLSURFACE
End Sub

Pystytkö luomaan yksinkertaisen tilanteen, jossa ongelma esiintyy?

vesimies [17.10.2007 11:33:02]

#

Kiitos vastauksesta!

Aluksi pieni lisäselvennys tuohon ongelmaan, RGB-arvojen "nollaan päättyminen" koskee heksadesimaalimuotoa. Tämä selviää kohta hyvin esimerkistä.

Antin esimerkki ei toiminut minulla! Se jo sinällään kertoo että jotain taitaa olla pielessä (mutta mitä?). Testailin tuota samaa juttua eri taustaväreillä:

Private Declare Function ExtFloodFill Lib "gdi32" ( _
ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _
ByVal crColor As Long, ByVal wFillType As Long) As Long

Private Const FLOODFILLBORDER = 0
Private Const FLOODFILLSURFACE = 1

Dim mlngTaustaVäri As Long

Private Sub Form_Load()
    ScaleMode = vbPixels
    Me.Show

    ' Tästä voi valita eri taustavärejä:
    mlngTaustaVäri = &HCB1D85 ' = RGB(133, 29, 203)  violetti
    'mlngTaustaVäri = &H808080 ' = RGB(128, 128, 128)  harmaa
    'mlngTaustaVäri = &H808181 ' = RGB(128, 129, 129)  harmaa
    'mlngTaustaVäri = &H818081 ' = RGB(129, 128, 129)  harmaa
    'mlngTaustaVäri = &H818181 ' = RGB(129, 129, 129)  harmaa

    ' piirretään täytetty violetti/harmaa neliö:
    Line (50, 50)-(100, 100), mlngTaustaVäri, BF
    ' piirretään sille turkoosi kehys:
    Line (50, 50)-(100, 100), RGB(57, 238, 155), B
    ' valitaan täyttöväriksi punainen:
    Me.FillColor = RGB(205, 49, 35)
    Me.FillStyle = vbSolid
    ' täytetään kuvion keskeltä reunoihin asti:
    ExtFloodFill Me.hdc, 75, 75, mlngTaustaVäri, FLOODFILLSURFACE
End Sub

Jotain tosi hämärää tapahtui! Tässä lopputulosten kuvat 4-kertaisesti suurennettuna, alla näkyy vastaava taustaväri: (vain kulma otettu kuvaan)

http://sooda.dy.fi/fpaste/index.php?AGl&avase (Soodalle kiitos filupastesta :)

:o

Blaze [17.10.2007 12:04:39]

#

Väris on jostain syystä ditheröity. Oon viimeks nähny tollasta kaverin 386:lla about 15 vuotta sitten o_O Oli muuten ärsyttävää kun paintbrushilla väritti alueen, ja sitten ei ditheröinnin takia voinu värittää sitä enää uuestaan toisella värillä. Mut takas aiheeseen.
Eihän sulla oo näyttöasetuksissa mitään hassua, kuten käytössä vaan 8-bittiset värit ("256 väriä")?

vesimies [17.10.2007 12:50:57]

#

On 16-bittiset värit käytössä (High Color). Hmm, pitäisköhän sitten olla 32-bittiset?! Kyllä kai 16-bittisillä jo pitäis toimia...

Blaze [17.10.2007 13:07:51]

#

vesimies kirjoitti:

Hmm, pitäisköhän sitten olla 32-bittiset?! Kyllä kai 16-bittisillä jo pitäis toimia...

Testaamalla oisit selvittäny jo :)
Mut joo, mun tietääkseni 16-bittinen näyttötila ei ditheröi.

vesimies [17.10.2007 13:31:10]

#

Taitaa olla niin että pitää olla 32-bittiset värit! Johan nyt. Laskinkin muuten nyt että täysi RGB-väritys tarvii 3*8 bittiä, eipä siinä 16 riitä... Jos nyt asian oikein haistoin.

No nyt tämä selvisi, kiitos Blaze! :)

vesimies [18.10.2007 14:35:25]

#

Nytpä keksin kuinka se toimii sekä 16- että 32-bittisillä väreillä:

Public Declare Function GetNearestColor Lib "gdi32" ( _
ByVal hdc As Long, ByVal crColor As Long) As Long

Private Function HaeHienoVäri() As Long
    Dim lngVäri As Long

    ' Käyttäjä valitsee värin:
    dlgDialogi.ShowColor
    lngVäri = dlgDialogi.Color

    'Pyöristetään väri lähimpään laitteen ymmärtämään väriin:
    HaeHienoVäri = GetNearestColor(Me.hdc, lngVäri)
End Function

Mielenkiintoisia muuten nuo 16-bittiset värit. Tutkiskelin niitä hieman. Niissä R- ja B- arvot ovat 0, 16, 24, 32, 40, ..., 248, 255 (mutta jostain syystä ei 8); ja G-arvot ovat tiheämmässä: 0, 8, 12, 16, 20, 24, ..., 248, 252, 255 (mutta jostain syystä ei 4). Tästähän voisi vaikka halutessaan laskea värien määrän. Ihan riittävästi niitä joka tapauksessa on tavalliseen kuviografiikkaan.

Blaze [18.10.2007 15:14:38]

#

vesimies kirjoitti:

Mielenkiintoisia muuten nuo 16-bittiset värit. Tutkiskelin niitä hieman. Niissä R- ja B- arvot ovat 0, 16, 24, 32, 40, ..., 248, 255 (mutta jostain syystä ei 8); ja G-arvot ovat tiheämmässä: 0, 8, 12, 16, 20, 24, ..., 248, 252, 255 (mutta jostain syystä ei 4).

R ja B ilmaistaan viiellä bitillä ja G kuuella (5+5+6 = 16), koska ihmissilmä havaitsee vihreen eri sävyt muita värejä paremmin.

vesimies kirjoitti:

Tästähän voisi vaikka halutessaan laskea värien määrän.

2^16 = 65536 erilaista väriä.
32-bittiset värit käyttävät oikeasti vain sen 24 (8 bittiä joka osavärille), nuo viimiset kahdeksan bittiä joko käytetään läpinäkyvyyden ilmaisemiseen (alpha) tai heitetään kokonaan hukkaan, koska näytönohjainrauta kuulemma käsittelee nopeammin 32 bitin kuin 24 bitin klönttejä.
24 bitillä saa 2^24 = 16777216 erilaista värisävyä.

vesimies [19.10.2007 11:21:28]

#

Blaze kirjoitti:

R ja B ilmaistaan viiellä bitillä ja G kuuella (5+5+6 = 16)

Sittenhän siinä ei ole yhtään "hukkabittejä" kuten 32-bittisissä väreissä. Tehokasta.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta