Hei,
Olen tähän asti käyttänyt GetPixeliä siihen että etsin pikselin tietystä ikkunasta, joka vastaa määriteltyä väriä. Mutta nykyisiin tarkoituksiin se on liian hidas.
Tässä esimerkki miten käytin GetPixeliä siihen, että siirsinn kursorin löydetyn pikselin x,y kohtaan:
Public Function CursorToColor(windowHWND As Long, colorcode As Long) Dim wndRect As RECT Dim X As Long, Y As Long, test As Long GetWindowRect windowHWND, wndRect test = GetDC(windowHWND) For Y = 0 To (wndRect.Bottom - wndRect.Top) For X = 0 To (wndRect.Right - wndRect.Left) If GetPixel(test, X, Y) = colorcode Then SetCursorPos X + wndRect.Left, Y + wndRect.Top ReleaseDC test, windowHWND Exit Function End If Next X Next Y ReleaseDC test, windowHWND End Function
Miten GetDiBitsiä voisi käyttää samalla tavalla kui käytän tuossa esimerkissä GetPixeliä? Yritin selvittää Googlella mutta en ymmärtänyt GetDiBitsistä yhtään mitään..
Tässä esimerkki missä käytettään GetDiBitsiä jonkin kuvan tarkasteluun tjs.
http://www.codeguru.com/vb/gen/vb_graphics/gdi/
Jos vaikka GetBitmapBits olisi helpompi:
Option Explicit Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Private Type RGBA Red As Byte Green As Byte Blue As Byte Alpha As Byte End Type Private Sub Form_Load() Dim Tavut() As RGBA, Leveys As Long, Korkeus As Long If Picture Is Nothing Then MsgBox "Aseta kuva formiin!" Else ' laske leveys & korkeus Leveys = ScaleX(Picture.Width, vbHimetric, vbPixels) Korkeus = ScaleY(Picture.Height, vbHimetric, vbPixels) ' alusta tavut ReDim Tavut(Leveys * Korkeus - 1) ' hae kaikki värit GetBitmapBits Picture.Handle, Leveys * Korkeus * 4, Tavut(0) ' tulosta ensimmäisen pikselin tiedot Debug.Print Tavut(0).Red, Tavut(0).Green, Tavut(0).Blue End If End Sub
En jaksa tähän hätään alkaa muistella, mikä on järkevin tapa hakea kuvan handle tunnetusta DC:stä, joten sen osan saat selvittää muualta tai odottaa jonkun toisen apua.
Sitten eräs muu asia joka voi kiinnostaa:
X = Indeksi Mod Leveys Y = Indeksi \ Leveys
Tämä lähinnä siksi, että moniulotteiset taulukot ovat hitaampia kuin yksiulotteinen. Lisäksi pitää pysytellä nollapohjaisuudessa, jotta tuota laskukaavaa ei tarvitse monimutkaistaa.
Täytyy testata onko tuokin väh. 3 kertaa nopeampi kuin GetPixel.
EDIT: Miten saisin tietoon noiden pikselien yhteismäärän että tiedän kuinka pitkälle pitää tarkistaa pikselit for loopissa?
Testaan tuota nyt punaisella kuvalla mutta jostain kumman syystä R:n arvo ei ole koko ajan 255 vaan sen sijaan G: tai B:n arvo :S
Sain nyt toimimaan GetDiBitsin niin että se etsii tietyn värin ikkunasta ja laittaa kursorin siihen kohtaan. Mutta millä laskukaavalla voin laskea mistä kohdasta värin tarkistus pitää aloittaa jos haluan aloittaa sen esim kohdasta 100,100?
Koko alueen pikseleiden määrän laskin width*height.
Ne pikselit menee siis näin.
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18
Esim kohta 10:n X on 1 ja Y on 2.
Eli miten lasken esim monesko 4,2 on? Se on 13.
Taitaa olla aika helppo juttu.. mutta silti kysyn :D
Yleisesti ottaen y * width + x (kun kaikki alkaa 0:sta)
Jos aloitat x:n ja y:n laskemisen 1:stä, mutta taulukko alkaa nollasta, niin:
(y - 1) * width + x - 1
Jos taulukkokin alkaa 1:stä kuten esimerkissäsi (harvemmin kuitenkaan alkaa oikeasti) niin
(y - 1) * width + x
Kiitoksia sain toimimaan etsimisen aloituskohdan, mutta pitääkö koko juttu koodata uudestaan jos haluan että se etsii esim alueelta 100,100-300,300, ilman että käy X akselia läpi 300:sta eteenpäin turhaan?
For Offset = startIndex To MaxOffset If ScreenBits(Offset) = color Then Dim x As Long, y As Long x = Offset Mod wndWidth y = Offset / wndWidth info.Caption = "Color " & color & " found at " & x & ", " & y Exit For End If Next Offset
MaxOffset = wndWidth * wndHeight startIndex = (Ystart - 1) * wndWidth + Xstart - 1
Voit esimerkiksi käyttää for loopin askellusta hyväksi:
For OffsetY = startIndex To MaxOffset Step wndWidth For Offset = OffsetY To OffsetY + 200 Next Offset Next OffsetY
Jostain syystä ei tänään riittänyt älykkyys tuon tajuamiseen vaikka näyttää aika helpolta^ :S
Mutta tässä on esimerkki ohjelman koodi niille, jotka sen haluaa. Etsii valitusta ikkunasta määritellyn värin getdibitsillä.
http://www.jrantala.com/getdibits.zip
Voit tehdä silmukat koordinaattien kanssa ja laskea offsetin silmukan sisällä.
For y = 100 To 300 OffsetY = y * wndWidth For x = 100 To 300 Offset = OffsetY + x ' ... Next Next
Toimintaselitys aiemmasta koodistani:
- startIndex = 100 - wndWidth = 300 - MaxOffset = 900 - For OffsetY = 100 - Onko OffsetY pienempi kuin MaxOffset (100 < 900)? -- For Offset = OffsetY (Offset = 100) -- Offset looppaa kunnes Offset > OffsetY + 200 -- Offset = 301, looppi päättyy - For OffsetY = OffsetY + wndWidth (OffsetY = 400) - Onko OffsetY pienempi kuin MaxOffset (400 < 900)? -- For Offset = OffsetY (Offset = 400) -- Offset looppaa kunnes Offset > OffsetY + 200 -- Offset = 601, looppi päättyy - For OffsetY = OffsetY + wndWidth (OffsetY = 700) - Onko OffsetY pienempi kuin MaxOffset (700 < 900)? -- For Offset = OffsetY (Offset = 700) -- Offset looppaa kunnes Offset > OffsetY + 200 -- Offset = 901, looppi päättyy - For OffsetY = OffsetY + wndWidth (OffsetY = 1000) - Onko OffsetY pienempi kuin MaxOffset (1000 < 900)? - Loppu tuli: looppien päättymisen jälkeen OffsetY = 1000 ja Offset = 901
Aihe on jo aika vanha, joten et voi enää vastata siihen.