我想创建一个位数组并将它们转换为vb中的位图?我知道如何创建像这样Dim NBitmap as new bitmap(width,height)
的位图,然后编辑像NBitmap.setpixel(x,y,color)
这样的像素。这很慢,但我认为创建一个数组或其他东西,然后将其转换为位图会更快。但我不知道如何...任何帮助都会很好!
例如:
Dim SM = DateTime.Now.Millisecond
Dim Texture As Bitmap = Image.FromFile("C:\Users\Noah\Desktop\graphics\Grass.jpg")
Dim w = 600
Dim h = 600
Dim Pixels(600, 600) As Color
Dim x = 0
Do Until x = 600
Dim y = 0
Do Until y = 600
Pixels(x, y) = Texture.GetPixel(x, y)
y += 1
Loop
x += 1
Loop
Dim EM = DateTime.Now.Millisecond
Dim FM = EM - SM
If FM < 0 Then
FM += 1000
End If
Dim FPS = 1000 / FM
Dim ETDFrame As New Bitmap(600, 600)
ETDFrame.image = Pixels().convertBMP
我知道这段代码不会起作用,但如果给出一个例子,我想要什么。我的目标是创建一个新的位图并编辑所有像素超快,足够快的3D游戏... < / p>
答案 0 :(得分:1)
目前还不清楚你要做什么。看起来好像是在尝试将.jpg转换为.bmp。如果是这样,您只需调用Image类的.Save
方法:
'Load the bitmap
Dim bm As Bitmap = Image.FromFile("C:\Users\Noah\Desktop\graphics\Grass.jpg")
'Save as .bmp
bm.Save("C:\Users\Noah\Desktop\graphics\Grass.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
如果您确实需要使用像素,那么使用GetPixel
和SetPixel
将会太慢。您需要使用LockBits
直接处理位图数据。像这样:
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Private Sub DoGraphics()
Dim x As Integer
Dim y As Integer
'PixelSize is 3 bytes for a 24bpp Argb image.
'Change this value appropriately
Dim PixelSize As Integer = 3
'Load the bitmap
Dim bm As Bitmap = Image.FromFile("C:\Users\Noah\Desktop\graphics\Grass.jpg")
'lock the entire bitmap for editing
'You can change the rectangle to specify different parts of the image if needed.
Dim bmData As BitmapData = bm.LockBits(New Rectangle(0, 0, bm.Width, bm.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bm.PixelFormat)
'Declare empty Color array
Dim pixels(bm.Width - 1, bm.Height - 1) As Color
'loop through the locked area of the bitmap.
For x = 0 To bmData.Width - 1
For y = 0 To bmData.Height - 1
'Get the various color offset locations for each pixel.
'This calculation is for a 24bpp rgb bitmap
Dim blueOfs As Integer = (bmData.Stride * x) + (PixelSize * y)
Dim greenOfs As Integer = blueOfs + 1
Dim redOfs As Integer = greenOfs + 1
'Read the value for each color component for each pixel
Dim red As Integer = Marshal.ReadByte(bmData.Scan0, redOfs)
Dim green As Integer = Marshal.ReadByte(bmData.Scan0, greenOfs)
Dim blue As Integer = Marshal.ReadByte(bmData.Scan0, blueOfs)
'Create a Color structure from each color component of the pixel
'and store it in the array
pixels(x, y) = Color.FromArgb(red, green, blue)
Next
Next
'Do something to the pixels array here:
For x = 0 To bmData.Width - 1
For y = 0 To bmData.Height - 1
pixels(x, y) = Color.Red
Next
Next
'Update the bitmap from the pixels array
For x = 0 To bmData.Width - 1
For y = 0 To bmData.Height - 1
'Get the various color offset locations for each pixel.
'This calculation is for a 24bpp rgb bitmap
Dim blueOfs As Integer = (bmData.Stride * x) + (PixelSize * y)
Dim greenOfs As Integer = blueOfs + 1
Dim redOfs As Integer = greenOfs + 1
'Set each component of the pixel
'There are 3 bytes that make up each pixel (24bpp rgb)
Marshal.WriteByte(bmData.Scan0, blueOfs, pixels(x, y).B)
Marshal.WriteByte(bmData.Scan0, greenOfs, pixels(x,y).G)
Marshal.WriteByte(bmData.Scan0, redOfs, pixels(x,y).R)
Next
Next
'Important!
bm.UnlockBits(bmData)
'Save the updated bitmap
bm.Save("C:\Users\Noah\Desktop\graphics\Grass.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
End Sub
我希望这会有所帮助。
更新:我已更新代码以显示更改像素值。
答案 1 :(得分:0)
不幸的是,Bitmap
类的属性没有返回所有像素颜色的数组/列表,因此您无法一次性设置它们。The Microsoft documentation page实际上提供了示例代码在两个嵌套循环中获取和设置像素颜色,就像你已经在做的那样。
如果您的最终目标是存储像素信息以传递给另一个Bitmap
,我建议the Clone method。不要花费时间和精力将数据提取到您自己的格式,而只需使用已经提供的数据。预定义的方法几乎总是最有效的,因此这应该是您表现最好的选择。
如果你真的必须将颜色存储在一个数组中,那么你必须编写一个循环遍历每种颜色的方法,并一次使用SetPixel
一个像素。这听起来就像你现在正在做的那样,所以这不会节省任何时间。