积极答复者
如何读取jpg格式图片的像素值到二位数组?

问题
-
VB2010如何不通过控件(批量图片,考虑速度要快)将jpg格式图片每点的像素值存储到二位数组,方便后续的图像处理?
http://social.msdn.microsoft.com/Forums/zh-CN/vbasiczhchs/thread/4581dd81-0bff-4c8c-b7a0-bf6e00ecf93b中指出可以通过MemoryStream 类的方法类在image对象和Byte Array之间进行转换,这个Byte Array能转到每点的像素值的二位数组吗?
- 已编辑 山顶的白羚 2011年12月26日 1:54
答案
-
读取进来,方法很多。效率最低的给你个
Dim bmp As Bitmap = Ctype(Image.FromFile(你的文件),Bitmap)
for x as integer to bmp.width
for y as integer to bmp.height
color c = bmp.GetPixel(x,y)'这就是你要的每个像素的颜色,自己按x,y存储到二维数组不是难题了吧。
next
next
2011 c# mvp China. *George读起来像不像“饺子”?我爱吃饺子,我叫George。- 已标记为答案 山顶的白羚 2011年12月30日 13:23
-
自己研究,自己支持。
先阅读帖子:
http://social.msdn.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/89bb346d-7a85-4e55-ad96-c3e7a5f9042b
为什么用内存方式对图象进行灰度化没效果中RickyLin的回答:
奇怪,我运行了你的代码,结果是正确的,图像灰化了。 我用VS2010 .NET Framework 3.5
Bitmap bmp = new Bitmap(@"C:\Users\rlin\Pictures\yingmu.jpg");
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmp.Width * bmp.Height * 3;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
double colorTemp = 0;
for (int i = 0; i < rgbValues.Length; i += 3)
{
colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = (byte)colorTemp;
}
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
bmp.UnlockBits(bmpData);
picBox.Image = bmp; // picBox is WinForm PictureBox control
虽然是c#代码,但LockBits方法和其中的for循环求得每个像素的RGB值并计算出灰度,应该用类似的方法可以实现“将jpg格式图片每点的像素值存储到二位数组”。
在vb 帮助文档中查到BitmapData 类http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.bitmapdata.aspx,其中有vb代码示例演示如何将 BitmapData 类与 LockBits 和 UnlockBits 方法一起使用。其中Marshal类的用法提高了运行效率。
Private Sub LockUnlockBitsExample(ByVal e As PaintEventArgs)
' Create a new bitmap.
Dim bmp As New Bitmap("c:\fakePhoto.jpg")
' Lock the bitmap's bits.
Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(rect, _
Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)
' Get the address of the first line.
Dim ptr As IntPtr = bmpData.Scan0
' Declare an array to hold the bytes of the bitmap.
' This code is specific to a bitmap with 24 bits per pixels.
Dim bytes As Integer = Math.Abs(bmpData.Stride) * bmp.Height
Dim rgbValues(bytes - 1) As Byte
' Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
' Set every third value to 255. A 24bpp image will look red.
For counter As Integer = 2 To rgbValues.Length - 1 Step 3
rgbValues(counter) = 255
Next
' Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)
' Unlock the bits.
bmp.UnlockBits(bmpData)
' Draw the modified image.
e.Graphics.DrawImage(bmp, 0, 150)
End Sub
再结合"Unsafe, But Fast!"http://blog.darkthread.net/post-2010-06-19-use-unsafe.aspx中观点,应该可以解决问题。
感谢Wei_Dong、George.Wuyazhe、Mike Feng的回复,选择George.Wuyazhe的为答案是因为可以让初学者迅速解决问题,虽然效率不高。
- 已建议为答案 ThankfulHeartModerator 2011年12月31日 2:06
- 已标记为答案 山顶的白羚 2012年1月14日 13:51
全部回复
-
我认为可以。得到的是一幅完整的图片的全部二进制像素的一维数组(不是二维!)
另外,直接可以使用System.IO.File.ReadAllBytes方法也可以。
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处 -
读取进来,方法很多。效率最低的给你个
Dim bmp As Bitmap = Ctype(Image.FromFile(你的文件),Bitmap)
for x as integer to bmp.width
for y as integer to bmp.height
color c = bmp.GetPixel(x,y)'这就是你要的每个像素的颜色,自己按x,y存储到二维数组不是难题了吧。
next
next
2011 c# mvp China. *George读起来像不像“饺子”?我爱吃饺子,我叫George。- 已标记为答案 山顶的白羚 2011年12月30日 13:23
-
我认为可以。得到的是一幅完整的图片的全部二进制像素的一维数组(不是二维!)
另外,直接可以使用System.IO.File.ReadAllBytes方法也可以。
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处
Mike Feng
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
自己研究,自己支持。
先阅读帖子:
http://social.msdn.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/89bb346d-7a85-4e55-ad96-c3e7a5f9042b
为什么用内存方式对图象进行灰度化没效果中RickyLin的回答:
奇怪,我运行了你的代码,结果是正确的,图像灰化了。 我用VS2010 .NET Framework 3.5
Bitmap bmp = new Bitmap(@"C:\Users\rlin\Pictures\yingmu.jpg");
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmp.Width * bmp.Height * 3;
byte[] rgbValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
double colorTemp = 0;
for (int i = 0; i < rgbValues.Length; i += 3)
{
colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = (byte)colorTemp;
}
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
bmp.UnlockBits(bmpData);
picBox.Image = bmp; // picBox is WinForm PictureBox control
虽然是c#代码,但LockBits方法和其中的for循环求得每个像素的RGB值并计算出灰度,应该用类似的方法可以实现“将jpg格式图片每点的像素值存储到二位数组”。
在vb 帮助文档中查到BitmapData 类http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.bitmapdata.aspx,其中有vb代码示例演示如何将 BitmapData 类与 LockBits 和 UnlockBits 方法一起使用。其中Marshal类的用法提高了运行效率。
Private Sub LockUnlockBitsExample(ByVal e As PaintEventArgs)
' Create a new bitmap.
Dim bmp As New Bitmap("c:\fakePhoto.jpg")
' Lock the bitmap's bits.
Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(rect, _
Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)
' Get the address of the first line.
Dim ptr As IntPtr = bmpData.Scan0
' Declare an array to hold the bytes of the bitmap.
' This code is specific to a bitmap with 24 bits per pixels.
Dim bytes As Integer = Math.Abs(bmpData.Stride) * bmp.Height
Dim rgbValues(bytes - 1) As Byte
' Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
' Set every third value to 255. A 24bpp image will look red.
For counter As Integer = 2 To rgbValues.Length - 1 Step 3
rgbValues(counter) = 255
Next
' Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)
' Unlock the bits.
bmp.UnlockBits(bmpData)
' Draw the modified image.
e.Graphics.DrawImage(bmp, 0, 150)
End Sub
再结合"Unsafe, But Fast!"http://blog.darkthread.net/post-2010-06-19-use-unsafe.aspx中观点,应该可以解决问题。
感谢Wei_Dong、George.Wuyazhe、Mike Feng的回复,选择George.Wuyazhe的为答案是因为可以让初学者迅速解决问题,虽然效率不高。
- 已建议为答案 ThankfulHeartModerator 2011年12月31日 2:06
- 已标记为答案 山顶的白羚 2012年1月14日 13:51