将字节数组转换为图像:参数无效

本文关键字:图像 参数 无效 转换 字节 字节数 数组 | 更新日期: 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;
        }
    }