字节数组到图像转换

我想将字节数组转换为图像。

这是我从哪里得到字节数组的数据库代码:

public void Get_Finger_print() { try { using (SqlConnection thisConnection = new SqlConnection(@"Data Source=" + System.Environment.MachineName + "\\SQLEXPRESS;Initial Catalog=Image_Scanning;Integrated Security=SSPI ")) { thisConnection.Open(); string query = "select pic from Image_tbl";// where Name='" + name + "'"; SqlCommand cmd = new SqlCommand(query, thisConnection); byte[] image =(byte[]) cmd.ExecuteScalar(); Image newImage = byteArrayToImage(image); Picture.Image = newImage; //return image; } } catch (Exception) { } //return null; } 

我的转换代码:

 public Image byteArrayToImage(byte[] byteArrayIn) { try { MemoryStream ms = new MemoryStream(byteArrayIn,0,byteArrayIn.Length); ms.Write(byteArrayIn, 0, byteArrayIn.Length); returnImage = Image.FromStream(ms,true);//Exception occurs here } catch { } return returnImage; } 

当我到达注释行时,会发生以下exception: Parameter is not valid.

我怎样才能解决造成这个exception的东西?

您正在向您的记忆stream写两次,也没有使用后的stream。 您还要求图像解码器应用embedded式色彩校正。

试试这个:

 using (var ms = new MemoryStream(byteArrayIn)) { return Image.FromStream(ms); } 

也许我错过了一些东西,但是对于我来说,这个一行代码可以很好地处理包含JPEG文件图像的字节数组。

 Image x = (Bitmap)((new ImageConverter()).ConvertFrom(jpegByteArray)); 

编辑:

这里看到这个答案的更新版本: 如何转换字节数组中的图像

 public Image byteArrayToImage(byte[] bytesArr) { MemoryStream memstr = new MemoryStream(bytesArr); Image img = Image.FromStream(memstr); return img; } 

所有呈现的答案都假定字节数组包含已知文件格式表示forms的数据,如:gif,png或jpg。 但是我最近有一个问题,试图将包含线性BGRA信息的byte[] s有效地转换成Image对象。 以下代码使用Bitmap对象解决它。

 using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; public static class Extensions { public static Image ImageFromRawBgraArray( this byte[] arr, int width, int height) { var output = new Bitmap(width, height); var rect = new Rectangle(0, 0, width, height); var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat); var ptr = bmpData.Scan0; Marshal.Copy(arr, 0, ptr, arr.Length); output.UnlockBits(bmpData); return output; } } 

这是在这个网站上发布的一个解决scheme略有变化。

我想指出@ isaias-b提供的解决scheme中存在一个错误。

该解决scheme假定stride等于行长度。 但事实并非总是如此。 由于GDI执行的内存alignment,跨度可以大于行长度。 这必须考虑在内。 否则会产生无效的移位图像。 填充每行中的字节将被忽略。

步幅是一行像素(扫描线)的宽度,四舍五入为四字节边界。

固定代码:

 using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; public static class ImageExtensions { public static Image ImageFromRawBgraArray(this byte[] arr, int width, int height, PixelFormat pixelFormat) { var output = new Bitmap(width, height, pixelFormat); var rect = new Rectangle(0, 0, width, height); var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat); // Row-by-row copy var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat) / 8; var ptr = bmpData.Scan0; for (var i = 0; i < height; i++) { Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength); ptr += bmpData.Stride; } output.UnlockBits(bmpData); return output; } } 

为了说明它可能导致什么,让我们生成PixelFormat.Format24bppRgb渐变图像101×101:

 var width = 101; var height = 101; var gradient = new byte[width * height * 3 /* bytes per pixel */]; for (int i = 0, pixel = 0; i < gradient.Length; i++, pixel = i / 3) { var x = pixel % height; var y = (pixel - x) / width; gradient[i] = (byte)((x / (double)(width - 1) + y / (double)(height - 1)) / 2d * 255); } 

如果我们将整个数组原样复制到bmpData.Scan0指向的地址,我们将得到以下图像。 因为图像的一部分被写入填充字节,所以被忽略。 这也是为什么最后一行是不完整的:

大步忽略

但是如果我们将通过bmpData.Stride值复制逐行移位目标指针,将生成有效的imaged:

跨步考虑在内

步幅也可能是负面的:

如果步幅是正的,则位图是自顶向下的。 如果步幅是负值,则位图是自下而上的。

但是我没有用这样的图像,这超出了我的笔记。

相关的答案: C# – RGB缓冲区从位图不同于C + +

尝试(更新)

 MemoryStream ms = new MemoryStream(byteArrayIn,0,byteArrayIn.Length); ms.Position = 0; // this is important returnImage = Image.FromStream(ms,true); 

你还没有宣布returnImage任何types的variables:)

这应该有所帮助:

 public Image byteArrayToImage(byte[] byteArrayIn) { try { MemoryStream ms = new MemoryStream(byteArrayIn,0,byteArrayIn.Length); ms.Write(byteArrayIn, 0, byteArrayIn.Length); Image returnImage = Image.FromStream(ms,true); } catch { } return returnImage; } 

这是受霍尔斯特布罗的回答启发,加上注释: 从字节数组获取图像对象

 Bitmap newBitmap; using (MemoryStream memoryStream = new MemoryStream(byteArrayIn)) using (Image newImage = Image.FromStream(memoryStream)) newBitmap = new Bitmap(newImage); return newBitmap; 

大多数情况下,这是SQL列中的错误数据。 这是插入图像列的正确方法:

 INSERT INTO [TableX] (ImgColumn) VALUES ( (SELECT * FROM OPENROWSET(BULK N'C:\....\Picture 010.png', SINGLE_BLOB) as tempimg)) 

大多数人这样做是不正确的:

 INSERT INTO [TableX] (ImgColumn) VALUES ('C:\....\Picture 010.png')) 

您好尝试下面的链接对我也有同样的问题,我解决了尝试下面的链接,这将有助于你在这里input链接描述