Преобразовать массив байтов в изображение: параметр недействителен - PullRequest
3 голосов
/ 13 января 2012

Я храню изображения в базе данных и хотел бы преобразовать их из байтового массива в изображение.У меня нет проблем с преобразованием объекта в байтовый массив, но я получаю сообщение об ошибке «Параметр неверен» при попытке преобразовать байтовый массив в изображение.Объект, который я передаю своему методу, взят из строки набора данных.

Хранимая процедура

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;
        }

Любые идеи будут полезны.

Ответы [ 5 ]

2 голосов
/ 13 января 2012

Image.FromStream, вероятно, выбрасывает ArgumentException, потому что формат изображения недопустим.Ожидать, что случайный сериализованный объект будет отформатирован как допустимое изображение, нецелесообразно.

1 голос
/ 13 января 2012

Используются ли данные, которые вы используете необработанные данные RGB? Если это так, в документации для FromStream () есть пользовательский комментарий, в котором упоминается, что метод сгенерирует, если поток содержит необработанные данные RGB: http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx (см. Внизу страницы); вместо этого рекомендуется использовать растровое изображение (http://msdn.microsoft.com/en-us/library/zy1a2d14.aspx).

1 голос
/ 13 января 2012

Попробуйте следующее, ваш поток может быть не инициализирован в начале:

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
}
0 голосов
/ 18 января 2012

Вам не нужен двоичный форматировщик, это то, что мешает вашим данным, это действительно для сериализации объектов.

Главное, что нужно отметить, это то, что объект уже является байтовым массивом, так что вы можете просто привестиэто и использовать это.

Попробуйте это: -

    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;
        }
    }
0 голосов
/ 13 января 2012

Решение Келси должно работать. Это потому, что когда вы читаете данные из byteArray в поток памяти, указатель помещается в конец потока, а теперь, когда вы пытаетесь прочитать данные из этого потока памяти, он пытается прочитать заголовок этого указателя, и, как нет данных после этого, вы получаете ошибку. Теперь, если вы сделаете ms.Seek(0, SeekOrigin.Begin);, указатель читателя будет помещен в начало потока памяти. И утилизируйте поток памяти, когда вы закончите, используя его ms.Dispose(). Надеюсь, это поможет.

...