2010-03-12 2 views
5

У меня есть сторонняя dll, которая генерирует растровое изображение и отправляет обратно ссылку. Если я сразу же сгенерирую System.Windows.Media.Imaging.BitmapSource, то все будет хорошо. Но если я сохранить ссылку и в дальнейшем (через несколько секунд, и многие вызовов функций) Я пытаюсь генерировать BitmapSource, я получаюПроходит System.Drawing.Bitmap через библиотеки классов ненадежны?

System.AccessViolationException было необработанного кодом пользователя
Message = Попытка чтения или написать защищенную память. Это часто указывает на то, что другая память повреждена. Источник = "System.Drawing"

при выполнении:

System.Windows.Media.Imaging.BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
    bmp.GetHbitmap(), 
    IntPtr.Zero, 
    Int32Rect.Empty, 
    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); 

Любые подсказки о том, что происходит здесь не так? Любые указатели будут полезны. Благодарю.

ответ

3

У меня была большая проблема с растровыми изображениями и нарушениями доступа. Я полагаю, что это происходит, так это то, что некоторые конструкторы bitmap оставляют открытые дескрипторы файлов, когда они этого не делают. Таким образом, программа, которую вы запускаете, обнаруживает, что файлы используются, когда их не должно быть.

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

Bitmap Temp = new Bitmap(inFullPathName); 
Bitmap Copy = new Bitmap(Temp.Width, Temp.Height); 
Copy.SetResolution(Temp.HorizontalResolution, Temp.VerticalResolution); 
using (Graphics g = Graphics.FromImage(Copy)) 
{ 
    g.DrawImageUnscaled(Temp, 0, 0); 
} 
Temp.Dispose(); 
return Copy; 

Очевидно, что для первой линии, ваш будет Bitmap Temp = MyThirdPartyDLL.GetBitmap(); или что-то. Если вы не заботитесь о разрешении может быть упрощено:

Bitmap Temp = MyThirdPartyDLL.GetBitmap(); 
Bitmap Copy = new Bitmap(Temp, Temp.Width, Temp.Height); 
Temp.Dispose(); 
return Copy; 

После внесения этих изменений, я был в состоянии сделать все виды файлов I/O, и т.д., прекрасно, надеюсь, что вы можете сделать одна и та же.

+0

К сожалению, это не имеет ничего общего с файловыми дескрипторами. См. Ответ Андраса для правильного объяснения. Однако мне понравилось ваше решение для копирования Bitmap для работы с ошибкой (+1). Если внутренние структуры данных mishal153 требуют Bitmap, а не BitmapSource, он должен использовать код, как вы опубликовали. Если нет, ему будет лучше всего просто создать BitmapSource сразу вместо создания нового Bitmap. –

+1

Hi Brandi, Ваши предлагаемые работы похожи на песню :). Благодаря! Я пытался сделать то же самое, но так, как я это делал, это: newBmp = oldBmp.Clone(); «Документация клона говорила:« Создает точную копию этого изображения », поэтому я подумал, что сделал глубокую копию. Что действительно запутывает, так это то, что документация конструктора Bitmap говорит: «Инициализирует новый экземпляр класса Bitmap из указанного существующего изображения», и это звучит как его просто обертывание существующего изображения, когда он делает глубокий copy :). Это только я или это смущает других. спасибо, ребята – mishal153

+0

Рад помочь. :) – Brandi

4

Я думаю, это означает, что дескриптор (ссылка на ресурс, управляемый операционной системой, а не .Net), возвращаемый bmp.GetHBitmap, уже недействителен - возможно, Dispose был вызван где-то или что-то в этом роде (не обязательно ваш код, хотя).

Я бы рекомендовал использовать другой способ сохранения данных растровых изображений, которые не полагаются на дескрипторы - возможно, сразу же вывести двоичные данные самого растрового изображения, а затем бросить ссылку на это.

Смежные вопросы