我想将字节数组转换为图像。
这是我获取字节数组的数据库代码:
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;
}
当我通过评论到达该行时,会发生以下异常:Parameter is not valid.
如何解决导致此异常的问题?
答案 0 :(得分:97)
您正在两次写入内存流,也不会在使用后丢弃该流。 您还要求图像解码器应用嵌入式颜色校正。
请改为尝试:
using (var ms = new MemoryStream(byteArrayIn))
{
return Image.FromStream(ms);
}
答案 1 :(得分:74)
也许我错过了一些东西,但对我来说这个单行程序可以正常工作,其中包含一个包含JPEG文件图像的字节数组。
Image x = (Bitmap)((new ImageConverter()).ConvertFrom(jpegByteArray));
编辑:
请点击此处查看此答案的更新版本:How to convert image in byte array
答案 2 :(得分:10)
public Image byteArrayToImage(byte[] bytesArr)
{
using (MemoryStream memstr = new MemoryStream(bytesArr))
{
Image img = Image.FromStream(memstr);
return img;
}
}
答案 3 :(得分:7)
我想注意@isaias-b提供的解决方案中存在一个错误。
该解决方案假设stride
等于行长度。但并非总是如此。由于GDI执行的内存对齐,步幅可能大于行长度。必须考虑到这一点。否则将生成无效的移位图像。每行中的填充字节将被忽略。
步幅是单行像素(扫描线)的宽度,四舍五入到四字节边界。
固定代码:
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
渐变图像101x101:
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:
Stride也可能是否定的:
如果步幅为正,则位图为自上而下。如果步幅是负数,则位图是自下而上的。
但我没有使用过这些图片,这超出了我的注意范围。
答案 4 :(得分:6)
有一个简单的方法如下,你可以使用图像的FromStream
方法来做到这一点,
请记住使用System.Drawing
;
// using image object not file
public byte[] imageToByteArray(Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
答案 5 :(得分:5)
尝试(更新)
MemoryStream ms = new MemoryStream(byteArrayIn,0,byteArrayIn.Length);
ms.Position = 0; // this is important
returnImage = Image.FromStream(ms,true);
答案 6 :(得分:5)
所有呈现的答案都假设字节数组包含已知文件格式表示的数据,如:gif,png或jpg。但是我最近在尝试将包含线性化BGRA信息的byte[]
转换为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;
}
}
这是在this site上发布的解决方案的略微变化。
答案 7 :(得分:2)
这是受到Holstebroe的回答的启发,以及这里的评论:Getting an Image object from a byte array
Bitmap newBitmap;
using (MemoryStream memoryStream = new MemoryStream(byteArrayIn))
using (Image newImage = Image.FromStream(memoryStream))
newBitmap = new Bitmap(newImage);
return newBitmap;
答案 8 :(得分:2)
您尚未将returnImage声明为任何类型的变量:)
这应该有所帮助:
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;
}
答案 9 :(得分:2)
一行:
Image.FromStream(new MemoryStream(byteArrayIn));
答案 10 :(得分:0)
大多数情况下,当发生这种情况时,它是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'))
答案 11 :(得分:0)
一个班轮:
Image bmp = (Bitmap)((new ImageConverter()).ConvertFrom(imageBytes));
答案 12 :(得分:0)
首先安装此软件包:
安装软件包SixLabors.ImageSharp-版本1.0.0-beta0007
[SixLabors.ImageSharp] [1] [1]:https://www.nuget.org/packages/SixLabors.ImageSharp
然后使用下面的代码将字节数组转换为图像:
Image<Rgba32> image = Image.Load(byteArray);
要使用以下代码获取ImageFormat:
IImageFormat format = Image.DetectFormat(byteArray);
对于突变图像,请使用以下代码:
image.Mutate(x => x.Resize(new Size(1280, 960)));
答案 13 :(得分:-2)
我发现了这些家伙 Convert array to image
private void button1_Click(object sender, EventArgs e)
{
try
{
string hasil = "D:\\coba1000.jpg";
System.IO.File.WriteAllBytes(@hasil, bytestosend);
pictureBox1.ImageLocation = @hasil;
}
catch { }
}