Ошибка параметра «Неправильно» в JpegBitmapDecoder - PullRequest
0 голосов
/ 04 июня 2018

Ошибка

An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Parameter is not valid.

Появляется в строке

decoder = new JpegBitmapDecoder(stream, bitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);

Трассировка стека

at System.Drawing.Image.get_Width()
at System.Drawing.Image.get_Size()
at System.Windows.Forms.PictureBox.ImageRectangleFromSizeMode(PictureBoxSizeMode mode)
at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Программа выполняет манипуляции с изображениями для групп файлов JPEG.

Функция, содержащая строку, вызывается неоднократно (для разных изображений) из GetWindowsTags и SetWindowsTags, и сбой происходит после переменного числа вызовов, но иногда быстрее с большими изображениями, что подразумевает проблемы с памятью.Однако мониторинг с помощью диспетчера задач не показывает систематического увеличения использования памяти при повторных вызовах.Неповторяемая природа ошибки (она не может быть обработана структурой try-catch) затрудняет понимание причины ее возникновения.

Полная функция в классе JpegMetadataAdapter

private BitmapFrame getBitmapFrame(string path)
    {
        BitmapDecoder decoder = null;
        using (Stream stream = System.IO.File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
        {
            decoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
        }
        BitmapFrame bf = decoder.Frames[0];
        decoder= null;           
        return bf;
    }

Функция getBitmapFrame вызывается из

public JpegMetadataAdapter(string path)
    {
        this.path = path;
        frame = getBitmapFrame(path);

        Metadata = (BitmapMetadata)frame.Metadata.Clone();
        //Metadata = (BitmapMetadata)frame.Metadata;
    }

Метаданные извлекаются функцией

public static void GetWindowsTags(string sFile, ref string Title, ref string Subject, ref string Comment, bool bShowError = false)
    {
            Cursor.Current = Cursors.WaitCursor;
            JpegMetadataAdapter jpeg = new JpegMetadataAdapter(sFile);
            Comment = (jpeg.Metadata.Comment + "").Trim();
            Title = (jpeg.Metadata.Title + "").Trim();
            Subject = (jpeg.Metadata.Subject + "").Trim();                              
            return;

    }

и устанавливаются функцией

public static void SetWindowsTags(string sFile, string sFileOut, string Title = "", string Subject = "", string Comment = "", bool bShowError = false)
    {
            var jpeg = new JpegMetadataAdapter(sFile);               
            jpeg.Metadata.Comment = Comment;
            jpeg.Metadata.Title = Title;
            jpeg.Metadata.Subject = Subject;
            jpeg.SaveAs(sFileOut);               
            return;
        }

GetWindowsTags вызывается 3 раза в цикле обработки для каждого входного файла и SetWindowsTags один раз

Следующий код иногда приводит к ошибке «недостаточно памяти», но не воспроизводимо.Массив строк LocalFilesToShow содержит 118 путей к файлам JPEG.Такое поведение очень странное и, возможно, указывает на что-то нехорошее в System.Drawing.dll на моей машине с Win 10.

//test of error in GetWindowsTags
                List<string> SearchResults = new List<string>();
                 for (int i = 0;  i < LocalFilesToShow.GetUpperBound(0); i++)
                {
                    string sTitle = "";
                    string sSubject = "";
                    string sComment = "";
                    GetWindowsTags(LocalFilesToShow[i], ref sTitle, ref sSubject, ref sComment);
                    if ((sTitle+ sSubject).IndexOf("NT") != 0)SearchResults.Add(LocalFilesToShow[i]);                      
                }`
...