06. april 2001 - 10:40Der er
25 kommentarer og 1 løsning
Scanlines og Pixels
Hvis jeg har en grafik linie der indeholder RGB værdier f.eks. RGB(100,120,10) RGB(200,150,240) RGB(90,40,80)... osv. Kan jeg så med Scanline \"scanne\" denne grafik-linie og indsætte de forskellige RGB værdier i en Tlistbox.
Det skulle gerne virke på samme måde som denne \"pixels\" eksempel (problemet med pixels metoden er bare at det tager mega laaaang tid):
var x,y,r,g,b : integer; begin for x := 0 to Tbitmap.width-1 do for y := 0 to Tbitmap.height-1 do begin r := getrvalue(Tbitmap.canvas.pixels[x,y]); g := getgvalue(Tbitmap.canvas.pixels[x,y]); b := getbvalue(Tbitmap.canvas.pixels[x,y]); Tlistbox.items.add(inttostr(r)+inttostr(g)+inttostr(b)); end;
I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
For y := 0 To Image1.Picture.Bitmap.Height-1 Do Begin SLin := Image1.Picture.Bitmap.ScanLine[y]; r0:= sLin^[2]; // Note: stored as BGR g0:= sLin^[1]; b0:= sLin^[0];
Borrisholt>> Jeg er ked af hvis jeg ikke kan finde ud af at formulere mig ordenligt. Jeg prøver lige igen...
Jeg vil via Scanline indsætte et bitmap-billeds RGB værdier ind i en Tlistbox.
Den skal have samme funktion som dette eksempel:
procedure TForm1.PixelsTest; var x, y, r, g, b : integer; begin
for x := 0 to Tbitmap.width-1 do for y := 0 to Tbitmap.height-1 do begin r := getrvalue(Tbitmap.canvas.pixels[x,y]); g := getgvalue(Tbitmap.canvas.pixels[x,y]); b := getbvalue(Tbitmap.canvas.pixels[x,y]);
Du er nødt til at vide hvilket pixelformat der er benyttet (Bitmap.PixelFormat - find constanterne i online hjælpen). Ud fra dette kendskab ved du så hvorledes de enkelte pixels er organiseret i linien. Så må du lavbe noget alá:
Var Pixel : LongWord; // Eller en eller anden stor-nok type
For Y := 0 To Bitmap.Heigth-1 Do For X := 0 To Bitmap.Width - 1 Do Begin SLine := Bitmap.ScanLine[y];
Pixel := SLine^[X*Pitch];
// Gør her det du vil med din pixel. Formatet afhænger af // pixelformat, så du skal no ha en case sætning her: Case FBitmap.PixelFormat Of pf32bit : ...; pf24bit : Begin // Colors stored as: [BGRx] // (x=Blue value for next pixel) R := Pixel SHR 4; G := Pixel SHR 8; B := Pixel SHR 12; End; pf16bit : ...; pf15bit : ...; pf8bit : Begin // Gray scale. R = G = B; R := Pixel SHR 12; G := Pixel SHR 12; B := Pixel SHR 12; End; Else Error - unknown pixelform exception End;
End;
Det er frit fra leveren, men jeg håber du kan bruge det....
Ups: ser lige alt alle mine Shift Right offsets i ovenstående kode kun skubber i 4 bit nibbles, ikke byute størrelse som det er krævet. Der skal derfor stå:
R := Pixel SHR 8; G := Pixel SHR 16; B := Pixel SHR 24;
Jeg ved det. Jeg har ikke specielt meget tid til at følge med i Delphi kategorien (desværre), så istedet kaster jeg mig pover enkelte spørgsmål - som jeg så prøver at følge til dørs.
Delphi>> Jeg tror jeg er ved at få det til at virke nu... Dog fatter jeg stadig ikke helt det med pixelformat 24bit osv. Men det må jeg kunne læse mig frem til et eller andet sted på nettet.
Det drejer sig kort fortalt om hvorledes RGB værdierne for de enkelte pixels er gemt. Ved Pixelformat pf24Bit, gemmes værdierne som 3 * 8 bit for hver pixel, i rækkefølgen BGR:
Forestil dig en linie startende med følgende pixels: Sort, Rød, Grøn, Blå, ....
Her vil dine scanline data, som bytes, være:
0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, ....
Bruges et andet Pixelformat, fx. pf8bit, vil RGB værdierne være gemt (pakket) på en anden måde. Ved pf(bit (grayscale) gemmes 8 bit for hver pixel - farver i gråtone scalaen er iøvrigt kendetegnet ved at R = G = B. Prøv med fx. Paint Shop Pro - hvis du sætter værdierne for R, G og B så vil du se at den resulterende farve er grå, intensiteten (lysstyrken om du vil) afhænger af den benyttede værdi.
Bruger du fx. pixelformatet pf15bit, så gemmes der for hver pixel 5 bit til farverne R, G og B. Du har dermed 2^5 = 32 varianseer for hver farve, hvilket resulterer i ialt 32768 farvekombinationer. Dataene vil være pakket lidt specielt:
B value for pixel 0: Byte 0, bit 7-3. G value for pixel 0: Byte 0, bit 2-0 + Byte 1, bit7-6. R value for pixel 0: Byte 1, bit 5-1 B value for pixel 1: Byte 1, bit 0 + Byte 2, bit 7-4. G value for pixel 0: Byte 2, 3-0 + Byte 3, bit 7 R value for pixel 0: Byte 3, bit 6-2 etc.
Som du kan se, så skal du faktisk ikke betragte en scanline som en byte stream/array, men som en bit stream. Så skal du med bitvis udmaskning og shift operationer trække RGB værdier ud for de enkelte pixels. Kun ved pixelformat pf8Bit, pf24Bit og pf32Bit passer det med at hver farves værdi er pakket som rene bytes - derfor er de også så hyppigt benyttede formater.
... hvis du sætter værdierne for R, G og B ENS så ...
der er også lidt ged for G og R værdierne for pixel 1 (et - ikke nul) i pf15Bit forklaringen.
Peter
(Hvorfor skal jeg altid læse korrektur på mine indlæg....)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.