将字节数组转换为图像:参数无效
本文关键字:图像 参数 无效 转换 字节 字节数 数组 | 更新日期: 2023-09-27 18:20:25
我将图像存储在数据库中,并希望将它们从字节数组转换为图像。我将对象转换为字节数组没有问题,但在尝试从字节数组转换为图像时,我收到了"参数无效"的错误。我传递给方法的对象来自数据集行。
存储过程
USE [----------------]
GO
/****** Object: StoredProcedure [dbo].[usp_imageloader_add_test] Script Date: 01/16/2012 09:19:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[usp_imageloader_add_test]
@p_Image Image
as
INSERT into Test_Images VALUES(@p_Image)
上传文件控件/将图像文件转换为字节数组并将数据保存到数据库
protected void btnUpload_Click(object sender, EventArgs e)
{
if (ctrlUpload.PostedFile != null)
{
if (ctrlUpload.PostedFile.ContentLength > 0)
{
// Get Posted File
HttpPostedFile objHttpPostedFile = ctrlUpload.PostedFile;
// Find its length and convert it to byte array
int ContentLength = objHttpPostedFile.ContentLength;
// Create Byte Array
byte[] bytImg = new byte[ContentLength];
// Read Uploaded file in Byte Array
objHttpPostedFile.InputStream.Read(bytImg, 0, ContentLength);
using (SqlConnection dbConnection = new SqlConnection(app_settings.sql_conn_string_db))
{
try
{
string sql = "usp_imageloader_add_test";
SqlCommand cmd = new SqlCommand(sql, dbConnection);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@p_Image", bytImg).SqlDbType = SqlDbType.Image;
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
catch (Exception ex)
{
ex.Message.ToString();
}
}
}
}
}
将对象转换为字节数组和图像
private System.Drawing.Image ObjToImg(object obj)
{
byte[] byteArray;
if (obj == null)
return null;
else
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
byteArray = ms.ToArray(); // Byte Array
ms.Close();
ms = new MemoryStream(byteArray, 0, byteArray.Length);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
return returnImage;
}
任何想法都会有所帮助。
Image.FromStream
可能正在抛出ArgumentException
,因为图像格式无效。期望随机序列化对象被格式化为有效图像是不合理的。
您使用的数据是原始RGB数据吗?如果是这样的话,FromStream()的文档中有一条用户评论提到,如果流包含原始RGB数据,该方法将抛出:http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx(见页面底部);它建议使用位图(http://msdn.microsoft.com/en-us/library/zy1a2d14.aspx)。
尝试以下操作,您的流可能不会初始化到开头:
ms = new MemoryStream(byteArray, 0, byteArray.Length);
ms.Seek(0, SeekOrigin.Begin);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
它是什么类型的图像?您确定存储的图像有效吗?
同样只是对用法的评论(不会影响您的问题),在处理流时使用using
语句是一种很好的做法。例如:
using (MemoryStream ms = new MemoryStream())
{
// your code here
}
Kelsey的解决方案应该可以工作。这是因为,当您将数据从byteArray读取到内存流时,指针被放置在流的末尾,而现在当您尝试从该内存流读取数据时,它会尝试读取该指针的头部,由于之后没有数据,因此会出现错误。现在,如果执行ms.Seek(0, SeekOrigin.Begin);
,则读取器指针将放置在内存流的开头。并在使用完内存流ms.Dispose()
后处理它。希望这能有所帮助。
您不需要二进制格式化程序,这就是扰乱数据的原因,它实际上是用于序列化对象的。
需要注意的关键是,该对象已经是一个字节数组,因此您可以对其进行强制转换并使用它。
试试这个:-
private System.Drawing.Image ObjToImg(object obj)
{
if (obj == null)
return null;
else
{
byte[] byteArray = (byte[])obj;
System.Drawing.Image returnImage;
using (var ms = new MemoryStream(byteArray, 0, byteArray.Length))
{
returnImage = System.Drawing.Image.FromStream(ms);
}
return returnImage;
}
}