Bitmaps + SetPixel = Fail

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von AliveDevil.

    Bitmaps + SetPixel = Fail

    Hi,

    mal wieder ich,
    dieses mal habe ich ein Problem mit Bitmaps und SetPixel...ja...SetPixel

    ich habe eine Funktion, die mir ein Array aus 4 Bytes in ein Image presst.
    Der Code:

    VB.NET-Quellcode

    1. Public Function GetImage() As Drawing.Bitmap
    2. Dim bitmap As Drawing.Bitmap = New Drawing.Bitmap(_width, _height)
    3. For x = 0 To _width
    4. For y = 0 To _height
    5. bitmap.SetPixel(x, y, colors(x, y).Color)
    6. Next
    7. Next
    8. Return bitmap
    9. End Function

    _height = 50
    _width = 50

    alles wunderschön, nur...wenn ich dann mit der Funktion

    VB.NET-Quellcode

    1. Dim bla As New MyImage(50, 50)
    2. bla.SetColor(0,0, New MyColor(255,255,255,255))
    3. bla.SetColor(50, 50, New MyColor(255, 255, 255, 255))
    4. Me.BackgroundImage = Bla.GetImage

    VB.NET-Quellcode

    1. Public Sub SetColor(ByVal x As Integer, ByVal y As Integer, ByVal color As MyColor)
    2. If colors(x, y) IsNot Nothing Then
    3. colors(x, y) = color
    4. End If
    5. End Sub


    Das Bild auf die Form zeichne, wird der Punkt "50,50" nicht gezeichnet.
    Benutzt ich statt "50,50", "49,49" wird ein "großes" 1 Px großes Rechteck in die untere Ecke gezeichnet.
    Der Punkt "0,0" wird aber auf das Image gezeichnet...so..bin ich nun zu dämlich..oder ist ein Bitmap zu bescheuert, den Punkt unten rechts richtig anzumalen?

    Gibts eine Lösung, dass zu umgehen, bzw. zu fixen?
    Im ersten Codeschnipsel wird bei Zeile 2 ein Bitmap Objekt mit der Höhe und Breite 50 erzeugt.
    Das heißt die Pixel gehen von 0 bis 49. Wenn jetzt versucht wird ab 50, 50 etwas zu zeichnen befindet sich das natürlich nicht mehr auf dem Bitmap Objekt. Ich weiß nicht genau, was ein MyImage Objekt ist aber wenn Du auf eine Bitmap mit der Größe 50, 50 zeichnen willst muss Du bei 0, 0 beginnen und bei 49, 49 aufhören.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    naja...das Problem dabei ist nur, dass ich dann ein Bild habe...das oben links einen kleinen Punkt als Pixel hat, und bei 49 49 ein riesengroßes Rechteck...
    MyImage ist eine eigene Klasse wegen eines Bildformates...GetImage und SetColor sind teil von dem MyImage
    Bild:holzshots.fessifi.de/holzshare/images/436b313.png

    du siehst..49,49 macht Probleme...
    das hier ist nur ein 5x5 Bild, damit man das besser sieht...Effekt ist aber derselbe
    MyImage ist eine eigens erstellte Klasse, damit ich Bilder in einem Spiel besser handlen kann
    MyColor ist ebenfalls eine eigene Klasse, damit ich ebenfalls die Bilder in dem Spiel besser handlen kann
    Sehr groß

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports FastGraphicsLib
    3. Public Class MyImage
    4. Private _width As Integer
    5. Private _height As Integer
    6. Private colors As MyColor(,)
    7. Public Function WriteToFile(ByVal file As String) As Boolean
    8. Dim stream As IO.FileStream = New IO.FileStream(file, IO.FileMode.OpenOrCreate, IO.FileAccess.Write)
    9. Dim array() As Byte = New Byte() {&HAA, CType(_width, Byte), &HAA, CType(_height, Byte), CType(Asc("|"c), Byte)}
    10. For Each item In array
    11. stream.WriteByte(item)
    12. Next
    13. For x = 0 To _width
    14. For y = 0 To _height
    15. 'writer.Write(color(x, y).R & color(x, y).G & color(x, y).B & color(x, y).Alpha & CType(x, Byte) & CType(y, Byte) & CType(Asc("|"c), Byte))
    16. If Not colors(x, y) Is Nothing Then
    17. stream.WriteByte(CType(x, Byte))
    18. stream.WriteByte(CType(Asc(":"c), Byte))
    19. stream.WriteByte(CType(y, Byte))
    20. stream.WriteByte(CType(Asc(":"c), Byte))
    21. stream.WriteByte(colors(x, y).R)
    22. stream.WriteByte(colors(x, y).G)
    23. stream.WriteByte(colors(x, y).B)
    24. stream.WriteByte(colors(x, y).Alpha)
    25. stream.WriteByte(CType(Asc("|"c), Byte))
    26. End If
    27. Next
    28. Next
    29. stream.Flush()
    30. stream.Close()
    31. stream.Dispose()
    32. Return True
    33. End Function
    34. Public Function WriteToByteArray() As Byte()
    35. Dim temparray As New List(Of Byte)
    36. With temparray
    37. .Add(&HAA)
    38. .Add(CType(_width, Byte))
    39. .Add(&HAA)
    40. .Add(CType(_height, Byte))
    41. .Add(CType(Asc("|"c), Byte))
    42. For x = 0 To _width
    43. For y = 0 To _height
    44. 'writer.Write(color(x, y).R & color(x, y).G & color(x, y).B & color(x, y).Alpha & CType(x, Byte) & CType(y, Byte) & CType(Asc("|"c), Byte))
    45. If Not colors(x, y) Is Nothing Then
    46. .Add(CType(x, Byte))
    47. .Add(CType(Asc(":"c), Byte))
    48. .Add(CType(y, Byte))
    49. .Add(CType(Asc(":"c), Byte))
    50. .Add(colors(x, y).R)
    51. .Add(colors(x, y).G)
    52. .Add(colors(x, y).B)
    53. .Add(colors(x, y).Alpha)
    54. .Add(CType(Asc("|"c), Byte))
    55. End If
    56. Next
    57. Next
    58. End With
    59. Dim bytes(temparray.Count - 1) As Byte
    60. Dim stream As New IO.MemoryStream(bytes, True)
    61. stream.Write(temparray.ToArray, 0, temparray.Count - 1)
    62. stream.Flush()
    63. stream.Close()
    64. stream.Dispose()
    65. Return bytes
    66. End Function
    67. Sub New(ByVal width As Integer, ByVal height As Integer)
    68. _width = width
    69. _height = height
    70. ReDim colors(_width, _height)
    71. For x = 0 To _width
    72. For y = 0 To _height
    73. colors(x, y) = New MyColor
    74. Next
    75. Next
    76. End Sub
    77. Public Function GetImage() As Drawing.Bitmap
    78. Dim bitmap As Drawing.Bitmap = New Drawing.Bitmap(_width, _height)
    79. 'Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(bitmap)
    80. For x = 0 To _width - 1
    81. For y = 0 To _height - 1
    82. 'g.FillRectangle(New Drawing.SolidBrush(colors(x, y).Color), New Drawing.Rectangle(x, y, 1, 1))
    83. bitmap.SetPixel(x, y, colors(x, y).Color)
    84. Next
    85. Next
    86. Return bitmap
    87. End Function
    88. Public Sub ReadFromByteArray(ByVal bytes() As Byte)
    89. Dim halt As Boolean = False
    90. Dim position As Integer = 0
    91. If Not bytes(position) = &HAA Then
    92. Throw New NotSupportedException("The fileformat is not supported")
    93. End If
    94. position += 1
    95. Dim width As Integer = 0
    96. Do Until halt
    97. If bytes(position) = &HAA Then
    98. halt = True
    99. Else
    100. width += bytes(position)
    101. End If
    102. position += 1
    103. Loop
    104. halt = False
    105. 'If Not bytes(position) = &HAA Then
    106. ' Throw New NotSupportedException("The fileformat is not supported")
    107. 'End If
    108. Dim height As Integer = 0
    109. Do Until halt
    110. If bytes(position) = CType(Asc("|"c), Byte) Then
    111. halt = True
    112. Else
    113. height += bytes(position)
    114. End If
    115. position += 1
    116. Loop
    117. halt = False
    118. Dim colors(width, height) As MyColor
    119. Dim x As Integer = 0
    120. Dim y As Integer = 0
    121. Dim r As Integer = 0
    122. Dim g As Integer = 0
    123. Dim b As Integer = 0
    124. Dim a As Integer = 0
    125. Dim state As String = "x"
    126. Do Until position > bytes.Length - 1
    127. If state = "x" Then
    128. If bytes(position) <> CType(Asc(":"c), Byte) Then
    129. x += bytes(position)
    130. Else
    131. state = "y"
    132. End If
    133. ElseIf state = "y" Then
    134. If bytes(position) <> CType(Asc(":"c), Byte) Then
    135. y += bytes(position)
    136. Else
    137. state = "r"
    138. End If
    139. ElseIf state = "r" Then
    140. r = bytes(position)
    141. state = "g"
    142. ElseIf state = "g" Then
    143. g = bytes(position)
    144. state = "b"
    145. ElseIf state = "b" Then
    146. b = bytes(position)
    147. state = "a"
    148. ElseIf state = "a" Then
    149. a = bytes(position)
    150. state = ""
    151. Else
    152. If bytes(position) = CType(Asc("|"c), Byte) Then
    153. colors(x, y) = New MyColor(CByte(r), CByte(g), CByte(b), CByte(a))
    154. x = 0
    155. y = 0
    156. r = 0
    157. g = 0
    158. b = 0
    159. a = 0
    160. state = "x"
    161. End If
    162. End If
    163. position += 1
    164. Loop
    165. End Sub
    166. Public Sub ReadFromFile(ByVal file As String)
    167. Dim stream As IO.FileStream = New IO.FileStream(file, IO.FileMode.Open, IO.FileAccess.Read)
    168. Dim bytes(CInt(stream.Length - 1)) As Byte
    169. stream.Read(bytes, 0, CInt(stream.Length - 1))
    170. ReadFromByteArray(bytes)
    171. End Sub
    172. Public Sub SetColor(ByVal x As Integer, ByVal y As Integer, ByVal color As MyColor)
    173. If colors(x, y) IsNot Nothing Then
    174. colors(x, y) = color
    175. End If
    176. End Sub
    177. End Class
    178. Public Class MyColor
    179. Private _R As Byte
    180. Private _G As Byte
    181. Private _B As Byte
    182. Private _Alpha As Byte
    183. Sub New()
    184. Me.New(0, 0, 0, 255)
    185. End Sub
    186. Sub New(ByVal r As Byte, ByVal g As Byte, ByVal b As Byte, ByVal alpha As Byte)
    187. _R = r
    188. _G = g
    189. _B = b
    190. _Alpha = alpha
    191. End Sub
    192. Public Function Color() As Drawing.Color
    193. Dim tcolor As Drawing.Color = Nothing
    194. tcolor = Drawing.Color.FromArgb(_Alpha, _R, _G, _B)
    195. Return tcolor
    196. End Function
    197. Public Property R As Byte
    198. Get
    199. Return _R
    200. End Get
    201. Set(ByVal value As Byte)
    202. _R = value
    203. End Set
    204. End Property
    205. Public Property G As Byte
    206. Get
    207. Return _G
    208. End Get
    209. Set(ByVal value As Byte)
    210. _G = value
    211. End Set
    212. End Property
    213. Public Property B As Byte
    214. Get
    215. Return _B
    216. End Get
    217. Set(ByVal value As Byte)
    218. _B = value
    219. End Set
    220. End Property
    221. Public Property Alpha As Byte
    222. Get
    223. Return _Alpha
    224. End Get
    225. Set(ByVal value As Byte)
    226. _Alpha = value
    227. End Set
    228. End Property
    229. End Class
    Bei mir sieht das so aus:
    Wie ist bei Dir BackgroundImageLayout eingestellt?
    Bilder
    • MyImage.jpg

      7,57 kB, 300×300, 103 mal angesehen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Mit Stretch ist mein Bild völlig schwarz.
    Teste mal einige der Eigenschaften und dann beschreib Dein Problem mit diesem Wissen noch einmal.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    also...
    Stretch war natürlich völlig falsch..hab Zoom...naja

    Mein Code zur generierung:

    VB.NET-Quellcode

    1. Dim bla As New MyImage(5, 5)
    2. bla.SetColor(0, 0, New MyColor(255, 255, 255, 255))
    3. 'bla.SetColor(49, 49, New MyColor(255, 255, 255, 255))
    4. bla.SetColor(4, 4, New MyColor(255, 255, 255, 255))
    5. Me.BackgroundImage = Bla.GetImage

    und die Sachen geben an:
    SetColor(x, y, MyColor(weiß))

    mit dem Code ist unten Rechts ein großes Rechteck
    oben Links ein kleiner Punkt
    mit SetColor(5,5,New MyColor(255,255,255,255))
    wird unten Rechts nichts gezeichnet.
    Alles klar. scheiß Visual Basic.
    Wenn Du Redim xxx(5) machst, werden die Indizes 0 bis 5, also 6 stück, erzeugt, deswegen knallt es nicht. Wegen Kompatibilität zu älteren VB-Versionen.
    Die Bitmap jedoch hat die Pixel 0 bis 4 in beiden Richtungen:

    VB.NET-Quellcode

    1. Public Function GetImage() As Drawing.Bitmap
    2. Dim bitmap As Drawing.Bitmap = New Drawing.Bitmap(_width, _height)
    3. 'Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(bitmap)
    4. For x = 0 To _width - 1 ' Deswegen
    5. For y = 0 To _height - 1 ' Deswegen
    6. 'g.FillRectangle(New Drawing.SolidBrush(colors(x, y).Color), New Drawing.Rectangle(x, y, 1, 1))
    7. bitmap.SetPixel(x, y, colors(x, y).Color)
    8. Next
    9. Next
    10. Return bitmap
    11. End Function
    Dein Code.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja. (4, 4) ist rechts unten.
    Nun verstehe ich aber Dein Problem nicht mehr. Es sollte doch nun alles klar sein. Oder?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Kann dieser Effect mit dem verschwommenen Riesenpix was mit Antialiasing zum tun haben?


    de.wikipedia.org/wiki/Skalierung_%28Computergrafik%29

    hier wird wohl die Bikubische Interpolation verwendet...
    (Ist bei GDI+ denke ich mit InterpolationMode einstellbar)...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    okay...so ich habs hinbekommen...dank RodFromGermany

    ich musste zwar noch etwas am Code ändern...aber jetzt funktioniert es...

    mit ein bisschen Manipulation des Auslese Codes..funktioniert nun auch das Anzeigen richtig...

    Am Ende nochmals Vielen Dank an alle, die sich die Mühe gemacht haben, mir bei meiner Dummheit zu helfen.. :P