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?
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?
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
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ä")?
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...
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.
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! :)
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.
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ä.
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.