Ошибка при загрузке изображения gdi 18

This is an expansion / qualification of Fred’s response which stated: «GDI limits the height of an image to 65534». We ran into this issue with one of our .NET applications, and having seen the post, our outsourcing team raised their hands in the air and said they couldn’t fix the problem without major changes.

Based on my testing, it’s possible to create / manipulate images with a height larger than 65534, but the issue arises when saving to a stream or file IN CERTAIN FORMATS. In the following code, the t.Save() method call throws our friend the generic exception when the pixel height is 65501 for me. For reasons of curiosity, I repeated the test for width, and the same limit applied to saving.

    for (int i = 65498; i <= 100000; i++)
    {
        using (Bitmap t = new Bitmap(800, i))
        using (Graphics gBmp = Graphics.FromImage(t))
        {
            Color green = Color.FromArgb(0x40, 0, 0xff, 0);
            using (Brush greenBrush = new SolidBrush(green))
            {
                // draw a green rectangle to the bitmap in memory
                gBmp.FillRectangle(greenBrush, 0, 0, 799, i);
                if (File.Exists("c:\\temp\\i.jpg"))
                {
                    File.Delete("c:\\temp\\i.jpg");
                }
                t.Save("c:\\temp\\i.jpg", ImageFormat.Jpeg);
            }
        }
        GC.Collect();
    }

The same error also occurs if you write to a memory stream.

To get round it, you can repeat the above code and substitute ImageFormat.Tiff or ImageFormat.Bmp for ImageFormat.Jpeg.

This runs up to heights / widths of 100,000 for me — I didn’t test the limits. As it happens .Tiff was a viable option for us.

BE WARNED

The in memory TIFF streams / files consume more memory than their JPG counterparts.

Rillaxac

Заблокирован

1

23.03.2015, 11:55. Показов 37295. Ответов 19

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

помогите пожалуйста при сохранении битмапа возникает такая ошибка: «В GDI+ возникла ошибка общего вида.»

делаю так:

C#
1
2
3
var bmp = new Bitmap(args[2]);
...
bmp.Save(args[2], System.Drawing.Imaging.ImageFormat.Bmp);



0



kolorotur

Эксперт .NET

17346 / 12757 / 3338

Регистрация: 17.09.2011

Сообщений: 21,036

23.03.2015, 12:10

2

Цитата
Сообщение от Rillaxac
Посмотреть сообщение

C#
1
var bmp = new Bitmap(args[2]);

Что находится в args[2]?
Оно понятно, что путь. Какой именно? Проверьте, чтобы он был корректен.

Цитата
Сообщение от Rillaxac
Посмотреть сообщение

Удалите эту часть — ошибка остается?



0



Rillaxac

Заблокирован

23.03.2015, 12:14

 [ТС]

3

Цитата
Сообщение от kolorotur
Посмотреть сообщение

Что находится в args[2]?
Оно понятно, что путь. Какой именно? Проверьте, чтобы он был корректен.

корректно, просто строка типа «picture.bmp»

Цитата
Сообщение от kolorotur
Посмотреть сообщение

Удалите эту часть — ошибка остается?

да



0



Эксперт .NET

17346 / 12757 / 3338

Регистрация: 17.09.2011

Сообщений: 21,036

23.03.2015, 12:18

4

Лучший ответ Сообщение было отмечено Rillaxac как решение

Решение

Цитата
Сообщение от Rillaxac
Посмотреть сообщение

да

Попробуйте тогда сохранить изображение под другим именем, например «picture_copy.bmp».



1



Rillaxac

Заблокирован

23.03.2015, 12:26

 [ТС]

5

Цитата
Сообщение от kolorotur
Посмотреть сообщение

Попробуйте тогда сохранить изображение под другим именем, например «picture_copy.bmp».

все уже и сам дошел, оказывается не нравится ему что я под тем же именем сохраняю…

Добавлено через 4 минуты
а не подскажите мне тогда как же все таки сделать чтобы сохранялось под тем же именем? это важно ! просто если я так сохраняю ошибка, пытался удалить файл перед сохранением пишет файл уже используется (соответственно моим же приложением, он же в битмап загружен), но мне надо именно под тем же именем принципиально !

Добавлено через 1 минуту
может быть можно получить как то этот битмап в буфер, закрыть объект и сохранить буфер в файл? только как получить объект в буфер?



0



kolorotur

Эксперт .NET

17346 / 12757 / 3338

Регистрация: 17.09.2011

Сообщений: 21,036

23.03.2015, 12:35

6

Цитата
Сообщение от Rillaxac
Посмотреть сообщение

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

Конечно:

C#
1
2
3
4
5
6
7
8
9
Bitmap bmp;
using (var fs = File.OpenRead(args[2]))
   bmp = new Bitmap(fs);
 
using (bmp)
{
   ...
   bmp.Save(args[2], System.Drawing.Imaging.ImageFormat.Bmp);
}



0



Rillaxac

Заблокирован

23.03.2015, 12:37

 [ТС]

7

Цитата
Сообщение от kolorotur
Посмотреть сообщение

Конечно:

ну можно и так а то я уже по другому решил))0

C#
1
2
3
4
5
var bmp = new Bitmap(args[2]);
var stream = new MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
bmp.Dispose();
File.WriteAllBytes(args[2], stream.GetBuffer());



0



Эксперт .NET

17346 / 12757 / 3338

Регистрация: 17.09.2011

Сообщений: 21,036

23.03.2015, 13:04

8

Цитата
Сообщение от Rillaxac
Посмотреть сообщение

а то я уже по другому решил

Так памяти в два раза больше на каждое изображение используется



0



UAA1979

0 / 0 / 1

Регистрация: 31.10.2014

Сообщений: 45

01.02.2017, 21:17

9

Предыстория тут

Теперь вот что у меня получается. Если изображение из базы, JPG Формата, то Выдает ошибку(смотрите вложение) а если .png то все работает. Вот код :

C#
1
2
3
4
5
6
7
8
9
10
11
 byte[] img = null;
                 
 
                    if (vessel_pic.Image != null)
                    {
                        MemoryStream ms = new MemoryStream();
                        vessel_pic.Image.Save(ms, vessel_pic.Image.RawFormat);
                        img = ms.ToArray();
 
                         
                    }

Миниатюры

При сохранении битмапа возникает такая ошибка: "В GDI+ возникла ошибка общего вида"
 



0



0 / 0 / 1

Регистрация: 31.10.2014

Сообщений: 45

04.02.2017, 05:19

10

Никто не ответит?



0



Администратор

Эксперт .NET

16317 / 12807 / 5059

Регистрация: 17.03.2014

Сообщений: 26,077

Записей в блоге: 1

04.02.2017, 07:48

11

UAA1979, посмотри есть ли вложенное исключение (InnerException) и если да, то что написано в нем. Для этого нажми на ссылку «View detail…» в окне исключения и VS покажет тебе полную информацию о исключении.



1



0 / 0 / 1

Регистрация: 31.10.2014

Сообщений: 45

09.02.2017, 01:37

12

Извините что так поздно отвечаю просто не заметил( Насчет ошибки я нажимаю показать детали но ничего нового не показывает:
System.Runtime.InteropServices.ExternalException occurred
HResult=-2147467259
Message=В GDI+ возникла ошибка общего вида.
Source=System.Drawing
ErrorCode=-2147467259
StackTrace:
в System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
в MWD_1.main_gate.v_add_btn_Click(Object sender, EventArgs e) в c:\Users\Karashka\Desktop\C#\MVD-2bad\MVD-2\main_gate.cs:строка 235
InnerException:

Миниатюры

При сохранении битмапа возникает такая ошибка: "В GDI+ возникла ошибка общего вида"
 



0



Администратор

Эксперт .NET

16317 / 12807 / 5059

Регистрация: 17.03.2014

Сообщений: 26,077

Записей в блоге: 1

09.02.2017, 16:14

13

UAA1979, раскрой исключение в окне View Detail и посмотри точно ли в InnerException ничего нет?



0



0 / 0 / 1

Регистрация: 31.10.2014

Сообщений: 45

09.02.2017, 19:04

14

И опять вы правы. Показывает нуль. Расскажу как бывает. Я выбираю из списка айтем. Он выбрасывает данные и изображение из базы на pictureBox. Я меняю данные но не изображение и хочу добавить как новый айтем. Вот тогда то и выходит эта ошибка. На pictureBox е по умолчанию стоит изображение и если нету изображения он добовляет эту. Но если из базы загрузить изображение то выходит эта ошибка.

Миниатюры

При сохранении битмапа возникает такая ошибка: "В GDI+ возникла ошибка общего вида"
 



0



0 / 0 / 1

Регистрация: 31.10.2014

Сообщений: 45

09.02.2017, 19:07

15

Да кстати если в базе pnq то нет проблем



0



Администратор

Эксперт .NET

16317 / 12807 / 5059

Регистрация: 17.03.2014

Сообщений: 26,077

Записей в блоге: 1

09.02.2017, 19:23

16

UAA1979, я как раз таки надеялся что в InnerException что-то будет. Посмотри чему равен в этот момент vessel_pic.Image и vessel_pic.Image.RawFormat для png и jpeg. Может с ними что-то не так.



0



UAA1979

0 / 0 / 1

Регистрация: 31.10.2014

Сообщений: 45

09.02.2017, 20:31

17

А как посмотреть не подскажите? Как то можно вывести изображение в

C#
1
MessageBox. Show

?



0



Администратор

Эксперт .NET

16317 / 12807 / 5059

Регистрация: 17.03.2014

Сообщений: 26,077

Записей в блоге: 1

09.02.2017, 20:44

18

UAA1979, запусти код под отладчиком



0



0 / 0 / 1

Регистрация: 31.10.2014

Сообщений: 45

14.02.2017, 22:45

19

Разобрался с отладчиком. Ничего не показывает просто на этом месте сценарий останавливается. Никакой ошибки ничего кроме то что выдает . 0 ошибок 0 предупреждений Где смотреть что передает в этот момент ума не приложу(

Миниатюры

При сохранении битмапа возникает такая ошибка: "В GDI+ возникла ошибка общего вида"
 



0



906 / 663 / 318

Регистрация: 23.10.2016

Сообщений: 1,543

15.02.2017, 13:48

20

UAA1979, кто ж в режиме Release дебажит!



0



Такая ошибка может возникнуть в том случае, если пытаться сохранять в уже открытый файл. То есть ресурс «Test2.jpg» ранее был открыт и не освобождён.

Так что ищите в своём коде, где у вас ещё используется «Test2.jpg» (и не освобождается при этом).


У вас не используются Dispose/using. Покажу, как должен выглядеть правильный код. Заодно поправил нейминг.

static void Edit(string text)
{
    using (var image = Image.FromFile("Test.jpg"))
    using (var graphics = Graphics.FromImage(image))
    using (var font = new Font("Xenia Font", 15, FontStyle.Bold))
    using (var brush = new SolidBrush(Color.WhiteSmoke))
    using (var stringFormat = new StringFormat())
    {
        graphics.DrawString(
            text,
            font,
            brush,
            new RectangleF(0, 0, 0, 340),
            stringFormat
        );

        image.Save("Test2.jpg", ImageFormat.Jpeg);
    }
}

Вообще, stringFormat вполне можно убрать, т. к. ему не задаются параметры, отличные от дефолтных.

RectangleF не является disposable, поэтому его не нужно заключать в using.

Также неясно, зачем метод сделан статическим.

Я загрузил изображение в Picture Box, используя:

picturebox1.Image = Image.FromFile()

и я сохраняю это с помощью:

Bitmap bm = new Bitmap(pictureBox1.Image);
bm.Save(FileName, ImageFormat.Bmp);

Он отлично работает при создании нового файла, но когда я пытаюсь заменить существующий образ, я получаю следующую ошибку во время выполнения:

В GDI+ произошла общая ошибка

Так что я могу сделать, чтобы решить эту проблему?

2011-08-18 09:55

9
ответов

Решение

Это потому, что файл изображения используется вашим picturebox1.Imageпопробуйте сохранить его в другой путь к файлу:

picturebox1.Image = Image.FromFile(FileName);
Bitmap bm = new Bitmap(pictureBox1.Image); 
bm.Save(@"New File Name", ImageFormat.Bmp);

Редактировать: вы также можете добавить копию с изображения в первую очередь, как:

picturebox1.Image = new Bitmap(Image.FromFile(FileName));
Bitmap bm = new Bitmap(pictureBox1.Image); 
bm.Save(FileName, ImageFormat.Bmp);//no error will occurs here.

2011-08-18 09:58

FromFile Метод блокирует файл, поэтому используйте метод Image.FromStream() для чтения изображения:

byte[] bytes = System.IO.File.ReadAllBytes(filename);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
pictureBox1.Image = Image.FromStream(ms);

Затем сохраните, как раньше.

2011-08-18 10:06

Это также может произойти, если путь не существует.

Вы можете создать каталог с помощью:

System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(FileName));

2013-04-30 19:16

Когда объект Bitmap или объект Image создается из файла, файл остается заблокированным в течение всего времени существования объекта. В результате вы не можете изменить изображение и сохранить его обратно в тот же файл, в котором оно было создано. http://support.microsoft.com/?id=814675

Произошла общая ошибка в GDI+, JPEG Image для MemoryStream:

Image.Save(..)  // throws a GDI+ exception because the memory stream is closed

http://alperguc.blogspot.in/2008/11/c-generic-error-occurred-in-gdi.html

РЕДАКТИРОВАТЬ: просто писать по памяти. Сохранение в «посредника» MemoryStream должно сработать:

Например, замените это:

Bitmap newBitmap = new Bitmap(thumbBMP);
thumbBMP.Dispose();
thumbBMP = null;
newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg);

с чем-то вроде:

string outputFileName = "...";
using (MemoryStream memory = new MemoryStream())
{
    using (FileStream fs = new FileStream(outputFileName, FileMode.Create, FileAccess.ReadWrite))
    {
        thumbBMP.Save(memory, ImageFormat.Jpeg);
        byte[] bytes = memory.ToArray();
        fs.Write(bytes, 0, bytes.Length);
    }
}

2015-06-10 13:00

Попробуй это.

picturebox1.Image = Image.FromFile(FileName);
Bitmap bm = new Bitmat(pictureBox1.Image); 
Image img = (Image)b;
img.Save(FileName, ImageFormat.Bmp);

2011-08-18 10:04

Общая ошибка произошла в GDI+

Я тоже столкнулся с той же проблемой. Я пробовал много способов решить эту проблему. Наконец, я нашел место, где я ошибся. Проблема в том, что я использовал пространство в пути к файлу, что недопустимо. Теперь он работает нормально после удаления пробела перед C после апострофа:

"SupplyItems":"C:\\inetpub\\HIBMS_Ver1\\BarcodeImages\\Supply\\"

вместо этого… я использовал один ниже.

"SupplyItems":" C:\\inetpub\\HIBMS_Ver1\\BarcodeImages\\Supply\\"

Незначительная ошибка, но потребовалось много времени, чтобы ее найти и исправить.

2019-08-01 13:22

Обратите внимание, что изображения, созданные Image.Clone(), по-прежнему будут вызывать ошибки GDI+, как показано нижеприведенным кодом BAD, вы должны использовать метод Image.FromStream() для чтения изображения, как показано в решении на этой странице.


    //BAD CODE: the image we will try to save AFTER the original image has been cloned and disposed
    Image clonedImage;
    //load image from file, clone it then dispose
    using (var loadedFromDiskImage = Image.FromFile(filePath))
    {
         clonedImage = (Image) loadedFromDiskImage.Clone();
    } 

//you might think the new image can be saved given the original is disposed
 //but this doesn't seem to be the way Clone() works
 //expect GDI+ error in line below:
 clonedImage.Save(filePath);

0

Источник


user1203112

18 сен '19 в 03:57
2019-09-18 03:57

2019-09-18 03:57

Как сказал @Jalal Aldeen Saa'd, окно с картинками использует файл и заблокировано от замены файла.

//unlock file by clearing it from picture box
if (picturebox1.Image != null)
{
   picturebox1.Image.Dispose();
   picturebox1.Image = null;
}

//put back the picture inside the pictureBox?


user3230406

14 ноя '15 в 04:23
2015-11-14 04:23

2015-11-14 04:23

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

private void LoadPictureBoxWithImage( string ImagePath)
{
    Stream objInputImageStream = null;
    BitmapData bmdImageData = null;
    Bitmap bmpSrcImage = null, bmTemp = null;
    byte[] arrImageBytes = null;
    int bppModifier = 3;
    try
    {

        objInputImageStream = new MemoryStream();
        using (FileStream objFile = new FileStream(ImagePath, FileMode.Open, FileAccess.Read))
        {
            objFile.CopyTo(objInputImageStream);
        }

        bmpSrcImage = new Bitmap(objInputImageStream);
        bppModifier = bmpSrcImage.PixelFormat == PixelFormat.Format24bppRgb ? 3 : 4;

        //reda from byte[] to bitmap               
        bmdImageData = bmpSrcImage.LockBits(new Rectangle(0, 0, bmpSrcImage.Width, bmpSrcImage.Height), ImageLockMode.ReadOnly, bmpSrcImage.PixelFormat);
        arrImageBytes = new byte[Math.Abs(bmdImageData.Stride) * bmpSrcImage.Height];

        System.Runtime.InteropServices.Marshal.Copy(bmdImageData.Scan0, arrImageBytes, 0, arrImageBytes.Length);
        bmpSrcImage.UnlockBits(bmdImageData);

        pbSetup.Image = (Bitmap)bmpSrcImage.Clone();
        pbSetup.Refresh();

    }
    catch (Exception ex)
    {
        throw new Exception("Error in Function " + System.Reflection.MethodInfo.GetCurrentMethod().Name + "; " + ex.Message);
    }
    finally
    {
        if (objInputImageStream != null)
        {
            objInputImageStream.Dispose();
            objInputImageStream = null;
        }
        if (bmdImageData != null)
        {
            bmdImageData = null;
        }
        if (bmpSrcImage != null)
        {
            bmpSrcImage.Dispose();
            bmpSrcImage = null;
        }
        if (bmTemp != null)
        {
            bmTemp.Dispose();
            bmTemp = null;
        }
        if (arrImageBytes != null)
        {
            arrImageBytes = null;
        }
    }

}


user9166962

03 янв '18 в 07:09
2018-01-03 07:09

2018-01-03 07:09

Попробуй это будет работать

public void SavePicture()
{
     Bitmap bm = new Bitmap(this.myBitmap)
     bm.Save("Output\\out.bmp" ,System.Drawing.Imaging.ImageFormat.Bmp );
}


user6502686

09 сен '16 в 10:12
2016-09-09 10:12

2016-09-09 10:12

Это также может произойти, если вы забудете добавить имя файла:

bm.Save(@"C:\Temp\Download", System.Drawing.Imaging.ImageFormat.Png);

И это можно исправить, добавив имя файла:

bm.Save(@"C:\Temp\Download\Image.png", System.Drawing.Imaging.ImageFormat.Png);

Примечание. На самом деле вам не нужно добавлять расширение, чтобы оно работало.


user3029887

13 окт '16 в 12:35
2016-10-13 12:35

2016-10-13 12:35

Другие вопросы по тегам
c#
bitmap
gdi+



Посмотрел предыдущие обсуждения темы «В GDI+ возникла ошибка общего вида». Не нашёл решения своего вопроса. Заранее благодарю за уделённое внимание.

Работаю в WINDOWS 7, Microsoft Visual Studio 2008.
Столкнулся с тем, что сохранение изображения в
Stream
работает не для всех картинок. Вот фрагмент кода:

public
Image
Изображение;

public
void
Записать(
Stream
поток ) {

  
Изображение.
Save( поток,
System.Drawing.Imaging.ImageFormat.Png
);

  
}

При выполнении сохранения некоторых картинок и возникает ошибка. Появление ошибки не зависит от размера картинки и от выбранного формата. Сами картинки я открывал и сохранял в другом формате в
Paint. Не помогает. Зато, помогает клавиша
PrtScr
. Тем же Paint
вырезаю картинку и сохраняю, и всё работает. Но, с большой картинкой (больше экрана) этот номер не проходит.

Помогите, кто знает как обойти эту неприятность. Спасибо!

Понравилась статья? Поделить с друзьями:
  • Ошибка при загрузке игры через торрент
  • Ошибка при загрузке варкрафт
  • Ошибка при загрузке гта 5 нажмите повтор
  • Ошибка при загрузке вайбер
  • Ошибка при загрузке голосового сообщения вк на компьютер