Entwickler-Ecke
Multimedia / Grafik - RGB Farben eines Bildes auslesen und in matrix speichern
Heider - Do 20.07.06 15:04
Titel: RGB Farben eines Bildes auslesen und in matrix speichern
hi!
hab mal ne Fragen zu meinen Quelltext (siehe unten). Ich will ein Bild mit Scanline auslesen und in ne Matrix schreiben um damit berechnungen (Fouriertransformation, etc) durchzuführen. Doch das Programm brich immer beim zweiten Pixel ab, der erste wird noch, so wie es aussieht korrekt in die matrix geschrieben.
Deklaration der Matrix Global
Delphi-Quelltext
1:
| imagematrix: array of array of array of Byte; |
Programmteil mit Fehler (so wies aussieht)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| function TfrmMain.GetColorMatrix(): Boolean; type PixArray = array[1..3] of Byte; var X, Y, I, J: Integer; pData: ^PixArray; bmp: TBitmap; begin bmp := TBitmap.Create; GetColorMatrix:= False; try with bmp do begin PixelFormat := pf24bit; bmp.assign(imgOrig.Picture); Width := bmp.Width; Height := bmp.Height; SetLength(imagematrix,Height); for I := Low(imagematrix) to High(imagematrix) do begin SetLength(imagematrix[I], Width); for J := Low(imagematrix[I]) to High(imagematrix[I]) do SetLength(imagematrix[I,J], 3); end; for Y := 0 to Height -1 do begin pData := bmp.ScanLine[Y];
for X := 0 to Width -1 do begin
imagematrix[X][Y][0] := pData^[1]; imagematrix[X][Y][1] := pData^[2]; imagematrix[x][Y][2] := pData^[3]; Inc(pData); end; end; end; finally bmp.Free; GetColorMatrix:= True end;
end; |
digi_c - Do 20.07.06 15:53
Ach wie ging das nochmal? RGB() war es nicht, ColourToRGB. Ohh diese Hitze...
Darf man fragen, wass du genau vor hast? Weil TBitmap.Canvas.Pixels[x,y]bzw. Scanlinewäre doch vielleicht optimaler?
JayEff - Do 20.07.06 16:10
Erstens: Er benutzt doch ScanLine ^^ Zweitens: Wo ist denn der Fehler und welcher tritt auf? Drittens würde ich das Result nicht im FINALLY (Das auch bei einer exception ausgelöst wird, also egal, ob eine auftritt oder nicht) auf True setzen, sondern im EXCEPT auf false!
Heider - Do 20.07.06 16:26
Also der Fehler tritt in zeile 33 bis 35 auf und ist ein Speicherzugriffsfehler, aber erst nachdem der erste Pixel ausgelesen und in die Matrix geschrieben wurde.
Ps. Danke für den Hinweis mit dem Except
F34r0fTh3D4rk - Do 20.07.06 18:24
warum benutzt du ein 3d array ? warum machst du net:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| type TRGBColor = record R, G, B: byte; |
Delphi-Quelltext
1: 2:
| var colormatrix: array of array of TRGBColor; |
? steigert die übersicht
Heider - Do 20.07.06 23:26
Also ich hab mir erstmal alle Tips zu herzen genommen und den Quelltext entsprechend geändert und aufeinmal scheints zu gehen. :D
hier der neue Quelltext
Globale Deklaration
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| type TRGBColor = record R, G, B: byte; end;
var imagematrix: array of array of TRGBColor; |
und hier der Programmteil
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| function TfrmMain.GetColorMatrix(): Boolean; type PixArray = array[1..3] of Byte; var I,J : Integer; pData: ^PixArray; bmp: TBitmap; begin bmp := TBitmap.Create; GetColorMatrix:= False; try with bmp do begin PixelFormat := pf24bit; bmp.assign(imgOrig.Picture); Width := bmp.Width; Height := bmp.Height; SetLength(imagematrix,Height); for I := Low(imagematrix) to High(imagematrix) do SetLength(imagematrix[I], Width); for I := 0 to Height -1 do begin pData := bmp.ScanLine[I]; for J := 0 to Width -1 do begin imagematrix[I][J].R := pData^[1]; imagematrix[I][J].G := pData^[2]; imagematrix[I][J].B := pData^[3]; Inc(pData); end; end; bmp.Free; GetColorMatrix:= True; end; Except bmp.Free; GetColorMatrix:= False; end; end; |
Vielen Dank für eure Hilfe!
Phantom1 - Fr 21.07.06 09:28
der Grund warum es bei dir mit dem ersten Quellcode oben nicht ging ist weil du:
Delphi-Quelltext
1: 2: 3:
| imagematrix[X][Y][0] := pData^[1]; imagematrix[X][Y][1] := pData^[2]; imagematrix[x][Y][2] := pData^[3]; |
du hast dort die X und Y dimension vertauscht gehabt.
so hätte es funktioniert:
Delphi-Quelltext
1: 2: 3:
| imagematrix[Y][X][0] := pData^[1]; imagematrix[Y][X][1] := pData^[2]; imagematrix[Y][X][2] := pData^[3]; |
Achja noch ein Tipp:
Delphi-Quelltext
1: 2: 3:
| SetLength(imagematrix,Height); for I := Low(imagematrix) to High(imagematrix) do SetLength(imagematrix[I], Width); |
Die function SetLength unterstützt mehrere Dimensionen, du brauchst also nur:
Delphi-Quelltext
1:
| SetLength(imagematrix, Height, Width); |
das bewirkt das gleiche wie dein Quellcode
Heider - Fr 21.07.06 12:45
Leider funktionierte es nur eine kurze Zeit, ich hab gestern abend noch den Quelltext um eine weitere Funktion ergänzt, aber die Funktion nicht weiter verändert, trotzdem funktionert es nun nicht mehr. Es gibt einen Speicherzugriffsfehler und die Zeile 29 der funktion wird markiert. Wieder wird nur der erste Pixel ausgelesen und danach kommt der Abbruch. Es ist zum verzweifeln.
Phantom1 - Fr 21.07.06 17:28
Heider hat folgendes geschrieben: |
Leider funktionierte es nur eine kurze Zeit, ich hab gestern abend noch den Quelltext um eine weitere Funktion ergänzt, aber die Funktion nicht weiter verändert, trotzdem funktionert es nun nicht mehr. Es gibt einen Speicherzugriffsfehler und die Zeile 29 der funktion wird markiert. Wieder wird nur der erste Pixel ausgelesen und danach kommt der Abbruch. Es ist zum verzweifeln. |
Tja iss schwer zu sagen, kann an vielen dingen liegen, zb wenn man ein jpg in das Image lädt, dann stürzt deine function auch ab.
Ansonsten probiere es mal so hier, habe nur kleine änderungen vorgenommen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| function TForm1.GetColorMatrix: Boolean; var X, Y: Integer; pData: ^TRGBColor; bmp: TBitmap; begin bmp := TBitmap.Create; try bmp.assign(imgOrig.Picture.Bitmap); bmp.PixelFormat := pf24bit; SetLength(imagematrix, Height, Width); for Y := 0 to Height -1 do begin pData := bmp.ScanLine[I]; for X := 0 to Width -1 do begin imagematrix[Y, X] := pData^; Inc(pData); end; end; bmp.Free; Result := True; except bmp.Free; Result := False; end; end; |
Heider - Sa 22.07.06 02:31
Danke Phantom1, ich hab deine Variante des Quelltextes benutzt und jetzt geht es. Könnte sein, dass die Deklaration von Pdata, die entscheidende Änderung war, oder halt doch irgendein dummer indexfehler.
Nochmals vielen Dank an alle die geholfen haben das Problem zu lösen!
Phantom1 - Sa 22.07.06 09:09
Heider hat folgendes geschrieben: |
Danke Phantom1, ich hab deine Variante des Quelltextes benutzt und jetzt geht es. Könnte sein, dass die Deklaration von Pdata, die entscheidende Änderung war, oder halt doch irgendein dummer indexfehler. |
Ne das war auch bei deiner Variante in Ordnung, ich habe es nur etwas vereinfacht.
Was mir jetzt noch eingefallen war, ist das du das Pixelformat an der richtigen stelle hättest setzen müssen.
Bei dir war es so:
Delphi-Quelltext
1: 2:
| bmp.pixelformat:=pf24bit; bmp.assign(img.picture.bitmap); |
Beim Assign wird jetzt alles vom img übernommen, das wären die Bilddaten, Größe und auch das Pixelformat! Daher muss das pixelformat nach dem assign gesetzt werden.
mfg
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!