字节数组到图像转换
我想将字节数组转换为图像。
这是我从哪里得到字节数组的数据库代码:
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链接描述