Lockbit fehler?
Hey,
ich habe gerade ein Problem, und ich verstehe absolut nicht warum. Ich verwende LockBit schon seit langem, und frage mich wirklich warum ich zur Zeit diesen Fehler habe. Nebenbei läuft in meinem Projekt seperat noch ein anderer Thread, wo die Lockbit Methode keinen Fehler macht. Liegt es eventuell daran?
Hier einmal ein Vergleich :
Über die Methode bmp.SetPixel
Code : PasteBin
Über LockBits
Code : Pastebin
Wenn ich bei der Lockbit Methode die Mitte der Bitmap mit einem Pixel rot Färbe, ist es nur leider nicht die Mitte. Für mich sieht es aus, als würde etwas mit dem offset nicht stimmen. Kann doch aber eigentlich nicht sein, da ich genau die gleiche Methode auch bei anderen Bildern verwende.
Einzig alleine das ich eventuell nicht 2 LockBit Funktionen parallel laufen lassen darf würde mir einfallen. Aber ob das stimmt weiß ich nicht.
Oder enthält meine Lockbit - Methode allgemeine Fehler?
LG
Sperre von den Links entfernt
Einzig alleine das ich eventuell nicht 2 LockBit Funktionen parallel laufen lassen darf würde mir einfallen. Aber ob das stimmt weiß ich nicht.
Kann ich entkräften. Hab es gerade in der Funktion getestet, die nach Abschluss der Threads über ein Event aufgerufen wird.
Dort sind alle Speicher bereits freigegeben, und keine weitere Threads am laufen. Demnach muss in meiner LockBit Methode ein Fehler sein.
Code kann nicht angezeigt werden. Login ist erforderlich.
Hier den Code von dem LockBit Sub. Die SetPixel Methode ist eh unwichtig
https://pastebin.com/mBHnp8CD
2 Antworten
Laut Documentation wird der Stride auf ein Vielfaches von 4 gerundet.
Leider geht aus der Documentation nicht hervor, ob dadurch Padding pro Zeile, Pro Pixel oder Pro Bitmap entsteht. In den ersten zwei Fällen würde dein Program aber falsche Ergebnisse liefern, da die Position falsch berechnet wird.
Jetzt musst du nur noch herausfinden, wo da ein Bit mehr verwendet wird. Ich darauf, dass das pro Zeile geschieht. Folglich schlicht Statt
y * bmp.Width * btps
direkt mit dem Stride rechnen.
Private bmp_clr_Palette As New Bitmap(rct_clr_Pallette.Width, rct_clr_Pallette.Height, PixelFormat.Format24bppRgb)
und die Position mit :
position = ((y * bmpData.Stride) + (x * btps)
Funktionieren. Nun, komme ich so aber zu der Frage, warum funktioniert der vorherige Code, in meiner Klasse ohne Probleme? Ist mir unerklärlich.
Wobei, könnte es evt. damit zusammenhängen dass mein Farbverlauf den ich hier erstellen wollte in Breite/Höhe = 265 sind. Und in meiner Klasse das Bild 1.5k/1k groß ist. ?
Wenn der Stride bereits durch 4 teilbar ist, dann hast du keine Rundung und es tritt kein fehler auf. Das hängt also von der verwendeten Bitmap ab sowie vom verwendeten Format.
Ich danke euch. Die Position werde ich ab sofort nur noch über Stride berechnen. Wird mir bestimmt viel Zeit für die Fehlersuche ersparen^^
Das Einzige, was mir auffällt, ist, dass Du zwar die Puffergröße über "Stride" berechnest, die Pixelposition im Array dann aber über bmp.Width und btps.
Nun das liegt doch daran, wie die Bitmap zerschnitten wird, und dann im Speicher abgelegt wird. Demnach gibt mir Stride die bytes in der horizontalen Länge.
Hier sollten 24bppRgb gemnach 3 Bytes entsprechen. Dafür dann auch die Variabel btps.
Ich verstehe es halt nicht, weil alle anderen Controls auf meiner Form ( außer die 3Scrollbaren und die Checkbox) werden über LockBits erstellt, und über die Form Paint Events entsprechend gezeichnet. Und dort funktioniert alles ohne Probleme, über genau die gleiche Methode.
Ja, ich kenne das im Endeffekt auch nur so, dass Stride und bmp.Width eigentlich sogar auf denselben Wert hinauslaufen, aber das ist das Einzige, was mir erklären würde, wie dieser Offset zustandekommt.
Schaust du bitte mal hier, die Variabel in der Überwachung.
Bild
Warum da 1 Byte mehr ist, verstehe ich gerade auch nicht. Sollten eigentlich 795 sein, wenn ich mich da jetzt nicht irre.
Ich mache es normalerweise so, dass ich manuell einen entsprechend großen Byte-Puffer erzeuge, diesen beschreibe und dann nur noch nach dem LockBits rüberkopiere.
Ja, wie ich mir dachte, es liegt am Offset. Auch wenn ich es gerade noch nicht ganz verstehe.
Habe das Format von 3x1Byte für R,G,B zu 4x1Byte zu R,G,B,A gewechselt. Siehe da, mit dem Offset von 4 funktioniert es plötzlich.
Warum da 1 Byte mehr ist, verstehe ich gerade auch nicht.
Siehe:
https://www.gutefrage.net/frage/lockbit-fehler#answer-370789889
Kommt hin, mit 3bpp komme ich mit Stride auf 796. Wenn ich aber die Breite mal 3 nehme, bleibt ein Byte übrig. Auf die Höhe gerechnet, hätte ich dann 265 Bytes die zu viel wären. Schein also mit dem Pixelformat der bitmap zusammen zuhängen. Nur hätte ich gerne R,G,B Töne. Die 265 * 265 Bytes für Alpha Töne könnte ich eigentlich einsparen.