Я немного путаюсь с тем, как .NET управляет изображениями, у меня есть следующий код для создания управляемого растрового изображения из неуправляемого HBitmap, сохраняющего альфа-канал.
public static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap)
{
Bitmap bmp = Bitmap.FromHbitmap(nativeHBitmap);
if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32)
return bmp;
BitmapData bmpData;
if (IsAlphaBitmap(bmp, out bmpData))
{
// MY QUESTION IS RELATED TO THIS
// IF CALL SUPPRESS_FINALIZE THE OBJECT
// IT WILL WORK, OTHERWISE IT FAILS
GC.SuppressFinalize(bmp);
return new Bitmap(
bmpData.Width,
bmpData.Height,
bmpData.Stride,
PixelFormat.Format32bppArgb,
bmpData.Scan0);
}
return bmp;
}
private static bool IsAlphaBitmap(Bitmap bmp, out BitmapData bmpData)
{
Rectangle bmpBounds = new Rectangle(0, 0, bmp.Width, bmp.Height);
bmpData = bmp.LockBits(bmpBounds, ImageLockMode.ReadOnly, bmp.PixelFormat);
try
{
return IsAlphaBitmap(bmpData);
}
finally
{
bmp.UnlockBits(bmpData);
}
}
private static bool IsAlphaBitmap(BitmapData bmpData)
{
for (int y = 0; y <= bmpData.Height - 1; y++)
{
for (int x = 0; x <= bmpData.Width - 1; x++)
{
Color pixelColor = Color.FromArgb(
Marshal.ReadInt32(bmpData.Scan0, (bmpData.Stride * y) + (4 * x)));
if (pixelColor.A > 0 & pixelColor.A < 255)
{
return true;
}
}
}
return false;
}
Хорошо, я знаю, что строка GC.SuppressFinalize(bmp);
не имеет смысла, но когда я удаляю эту строку, иногда (каждые 4 или 5 вызовов) я получаю следующее исключение:
Попытка чтения или записи в защищенную память. Это часто
признак того, что другая память повреждена.
Я подозреваю, что сборщик мусора собирает объект bmp до отрисовки возвращаемого растрового изображения, поэтому он пытается получить доступ к битам, расположенным в платформе. Если я никогда не собираю bmp, это работает, но это вызывает утечку памяти (ссылка на bmp никогда не собирается).
Знаете, как я мог решить эту проблему?