Zdravím, [Visual Studio 2010 Profesional, Framework 3.5, Visual Basic] podle postupu z http://msdn.microsoft.com/en-us/library/... pracuji s polem bajtů z bitmapy. Vše mi funguje bezproblémů do doby dokud nenastavím rozměry bitmapy na liché. Potom se mi vykreslený obrázek rozpadne. Jak to!?! Obr1: http://imageshack.us/photo/my-images/28/... Obr2: http://imageshack.us/photo/my-images/836... Kód1: http://www.edisk.cz/stahni/62168/BMPRozb...
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Imports System.Drawing.Imaging
Imports System.Math
Public Class Form1
Private BMP As New Bitmap(285, 291, PixelFormat.Format24bppRgb)
Private REC As New Rectangle(0, 0, BMP.Width, BMP.Height)
Private BMPData As BitmapData = BMP.LockBits(REC, ImageLockMode.ReadWrite, BMP.PixelFormat)
Private Ptr As IntPtr = BMPData.Scan0
Private BITY As Integer = Abs(BMPData.Stride) * BMP.Height
Private RGB(BITY - 1) As Byte
Private Sub Ctverec()
Marshal.Copy(Ptr, RGB, 0, BITY)
For X As Integer = 10 To 100
For Y As Integer = 10 To 100
'Převedeme dvojici souřadnic X a Y do podoby
'jednorozměrného indexu pole(uff...)
'tak že vynásobýme Y šířkou a ještě 3
'protoře je každý pixel reprezentován třemi
'hodnotami barev a přičteme X * 3
Me.RGB(Y * BMP.Width * 3 + X * 3) = 255
'výsledek by měl být modrý čtverec(10,10,100,100)
'Co se ale stane když nastavím bitmapu na liché
'rozlišení, třeba 285x291?
'Něják se to rozjede...
Next
Next
Marshal.Copy(RGB, 0, Ptr, BITY)
BMP.UnlockBits(BMPData)
End Sub
Private Sub Vykreslit(ByVal S As Object, ByVal e As PaintEventArgs) Handles Me.Paint
Ctverec()
e.Graphics.DrawImage(BMP, 0, 0)
End Sub
End Class
Protože v kódu nemohu najít chybu, usoudil jsme že mu naprosto nerozumím a nemůžu ho použít bez toho abych ho naplno pochopil. Proto prosím někoho kdo má trpělivost s tak beznadějným případem jako jsem já aby mi vysvětlit následujíí: Kód2: http://www.edisk.cz/stahni/85939/BMPVysv... 1) Proč se musí metodě LockBits() předávat obdelník? 2) Co za datový typ je IntPtr? Vidím ho poprvé. 3) Co je BitmapData.stride(). Proč je v kódu použita absolutní hodnota 4) Co přesně dělá Marshal.Copy()?
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Imports System.Drawing.Imaging
Imports System.Math
Public Class Form1
'Vytvořím novou bitmapu 300x300 s 24 bitouvou barevnou hloubkou.
Private BMP As New Bitmap(300, 300, PixelFormat.Format24bppRgb)
'Obdélník :D začátek na 0x0 to znamená na začátku souřadného systému.(normálně vlevo nahoře)
's velikostí 300x300(nebo to co se nastaví konstruktoru bitmapy)
Private REC As New Rectangle(0, 0, BMP.Width, BMP.Height)
'Uzamkuntí Bitů. Nevím proč to potřebuje obdélník. Asi proto aby se vědelo který bity to má zamknout?
Private BMPData As BitmapData = BMP.LockBits(REC, ImageLockMode.ReadWrite, BMP.PixelFormat)
'Tak tady je zvláštnost. Co je to datový týp IntPtr? Vím jenom že to je nějákej Integer :D.
Private Ptr As IntPtr = BMPData.Scan0
'Stride. Předpokládám že to vrátí počel pixelu na řádku vynásobeno počtem hodnot reprezentující barvu(doufám že 3)
'Proč je to ale zabaleno ve funkci math.abs()? Vrací to snad zápornou hodnotu?
Private BITY As Integer = Abs(BMPData.Stride) * BMP.Height
'Pole do kterého budeme ukládat hodnoty barevných složek pixelů
Private RGB(BITY - 1) As Byte
Private Sub Ctverec()
'Tak tady potřebuju vědět jak to fungule.
'zdroj, cíl, start index, a délka
'Jakto že můžu použít jako zdroj číslo?(IntPtr)
Marshal.Copy(Ptr, RGB, 0, BITY)
'Každá třetí hodnota v poli bude mít hodnotu 255
'začínám od nuly takže by výsledek měl být červený(Red Green Blue)
'ale je to modrý :( (asi to je BGR (blue green red))
For i As Integer = 0 To BITY - 1 Step 3
Me.RGB(i) = 255
Next
'Pff
Marshal.Copy(RGB, 0, Ptr, BITY)
'Nakonec musíme btity odemknout
BMP.UnlockBits(BMPData)
End Sub
'No tak vykreslíme výsledek
Private Sub Vykreslit(ByVal S As Object, ByVal e As PaintEventArgs) Handles Me.Paint
Ctverec()
e.Graphics.DrawImage(BMP, 0, 0)
End Sub
End Class
|