преобразовать byte[] в изображение

Я загрузил изображение в свою базу данных как byte[] и теперь пытаюсь отобразить его.

Произошла ошибка. Исключение аргумента не было обработано кодом пользователя Parameter is not valid.

На этой линии

newImage = System.Drawing.Image.FromStream(stream);

Вот мои коды

for (int i = 0; i < topRatingList.Count; i++)
            {
                int commentRating = topRatingList[i].CommentRating;
                int drinkID = topRatingList[i].DrinkID;

                if (i == 0)
                {
                    DrinkMenuDAO drink = DrinkMenuBLL.getDrinkMenu(drinkID);
                    LinkButton1.Text = drink.DrinkName; 
                    ImageButton1.ImageUrl = byteArrayToImage(drink.DrinkImage);
                }
            }


private string byteArrayToImage(byte[] byteArrayIn)
    {
        System.Drawing.Image newImage;
        string strFileName = Server.MapPath("~/Temp/images/") + ".jpg";
        if (byteArrayIn != null)
        {
            using (MemoryStream stream = new MemoryStream(byteArrayIn))
            {
                newImage = System.Drawing.Image.FromStream(stream);
                newImage.Save(strFileName);
            }
            return strFileName;
        }
        else
        {
            return "";
        }
    }

код, который я использовал для хранения изображения

protected void bn_upload_Click(object sender, EventArgs e)
    {
        lbl_msg.Text = "";
        Stream imgStream = FileUpload1.PostedFile.InputStream;
        BinaryReader imgBinary = new BinaryReader(imgStream);
        bytes = imgBinary.ReadBytes((Int32)imgStream.Length);
        imgBinary.Close();
        imgStream.Close();
        string src = byteArrayToImage(bytes);
        if (src.Equals(""))
        {
        }
        else
        {
            Image1.ImageUrl = "~/Temp/UploadedImage.jpg";
        }
    }

    private string byteArrayToImage(byte[] byteArrayIn)
    {
        System.Drawing.Image newImage;
        string strFileName = Server.MapPath("~/Temp/") + "UploadedImage.jpg";
        if (byteArrayIn != null)
        {
            using (MemoryStream stream = new MemoryStream(byteArrayIn))
            {
                newImage = System.Drawing.Image.FromStream(stream);
                newImage.Save(strFileName);
            }
            return strFileName;
        }
        else
        {
            return "";
        }
    }

    protected void btn_submit_Click(object sender, EventArgs e)
    {
        DrinkMenuBLL.uploadImg(bytes);
        lbl_msg.Text = "uploaded";
    }

Я использовал varbinary(MAX) в базе данных и sql, который я использовал

public static void UploadImg(byte[] drinkImage)
    {

        SqlConnection con = new SqlConnection(Constring.getConString());

        string sql = "Update DrinkMenu set drinkImage = (@imgData) where drinkID = 4";

        SqlCommand cmd = new SqlCommand(sql, con);
        cmd.Parameters.Add("@imgData", SqlDbType.Binary).Value = drinkImage;
        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }
        finally
        {
            con.Close();
            cmd.Dispose();
            con.Dispose();
        }
    }

person sihao    schedule 16.01.2013    source источник
comment
Вы уверены, что ваш byte[] правильно представляет изображение? Можем ли мы увидеть код, который его хранит?   -  person bluevector    schedule 16.01.2013
comment
байты = imgBinary.ReadBytes((Int32)imgStream.Length); Это не лучший способ чтения файла. У Джона Скита есть хороший ответ здесь: stackoverflow.com/questions/221925/ (раньше у него был отличный пост в блоге, в котором обсуждались различные методы, но я не могу его найти).   -  person Pete    schedule 16.01.2013


Ответы (1)


Одной из проблем может быть следующая:

bytes = imgBinary.ReadBytes((Int32)imgStream.Length);

Что делать, если длина потока больше, чем Int32.MaxValue, поскольку это Int64? Возможно, вы усекаете свое изображение... вместо этого используйте этот метод для чтения потока в буфер:

public static Byte[] ReadStream(Stream input)
{
    Byte[] buffer = new Byte[(16 * 1024)];

    using (MemoryStream stream = new MemoryStream())
    {
        Int32 read;

        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            stream.Write(buffer, 0, read);

        return stream.ToArray();
    }
}

protected void bn_upload_Click(object sender, EventArgs e)
{
    lbl_msg.Text = "";

    Byte[] bytes = ReadStream(FileUpload1.PostedFile.InputStream);
    String src = byteArrayToImage(bytes);

    if (!src.Equals(""))
        Image1.ImageUrl = "~/Temp/UploadedImage.jpg";
}
person Tommaso Belluzzo    schedule 16.01.2013
comment
извините, но я совершенно не понимаю .. как мне его использовать? - person sihao; 16.01.2013
comment
проблема с кодом загрузки? дело не в дисплейной части с потоком памяти? что упоминается выше этого? - person sihao; 16.01.2013
comment
Смотрите мой комментарий к исходному вопросу. - person Pete; 16.01.2013
comment
В следующий раз я буду использовать что-то другое, как вы предпочитаете. D: Во всяком случае, именно так поток должен правильно читаться: S - person Tommaso Belluzzo; 16.01.2013
comment
Для части загрузки у меня есть img1, и она показывает изображение, которое я собираюсь загрузить. Проблема заключается в том, что после сохранения в базе данных я беру из базы данных байты и преобразовываю их обратно в изображение. - person sihao; 16.01.2013
comment
Я согласен. Я просто подумал, что это забавно, что я разместил ссылку, и почти в тот же момент вы разместили код из ссылки... Но ссылка также объясняет, почему его метод не сработает (потому что Stream.Read не обязательно вернет столько как вы просите, и в частности, сетевые потоки, которые будут возвращать пакет за раз). - person Pete; 16.01.2013
comment
Вот что я получаю после смены кодов. System.Data.SqlClient.SqlException: The parameterized query '(@imgData binary(8000))Update DrinkMenu set drinkImage = (@imgDa' expects the parameter '@imgData', which was not supplied. - person sihao; 16.01.2013
comment
Пробовали ли вы отлаживать байтовые данные, чтобы убедиться, что теперь все в порядке с тем, что касается чтения потока? Вы проверили содержимое Byte[] в функции загрузки SQL? Кажется, между ними что-то не так... - person Tommaso Belluzzo; 16.01.2013
comment
Команда SqlCommand = .... command.Text=INSERT INTO YOUR_TABLE_NAME (image) значения (@image); command.Parameters.AddWithValue(@imgData, drinkImage); команда.ВыполнитьНеЗапрос(); - person Tommaso Belluzzo; 16.01.2013
comment
Я обновляю базу данных, которая в настоящее время не имеет значения изображения. - person sihao; 16.01.2013