Это, вероятно, не очень хорошо сформулированный вопрос, потому что я не уверен, что происходит, поэтому я не знаю, как его спросить. Я пытаюсь учиться, и я надеюсь, что смогу получить какое-то направление. Ваше терпение с неофитом оценено.Два разных GCHandle ссылаются на тот же массив в памяти
У меня есть часть кода, которую я модифицирую. Он отображает изображение. Я хочу изменить изображение и отобразить его в другом окне. Я копирую код, который отображает изображение, выполняет модификацию и отображает измененное изображение как для исходного, так и для измененного изображения.
Кажется, что GCHandle продолжает ссылаться на ту же память? Разве я не создаю новый дескриптор, изменив имя дескриптора? Извините за длинный фрагмент кода, но я просто потерялся.
Что происходит не так?
Самое недоумение в том, что он работал, затем я что-то изменил, и теперь я не могу вернуться к рабочей версии, потому что мой код такой же, как тот, который работал. Некоторые устанавливают где?
System.Runtime.InteropServices.GCHandle gch3 = System.Runtime.InteropServices.GCHandle.Alloc(scaled, System.Runtime.InteropServices.GCHandleType.Pinned);
int pitch = mImageWidth;
if (pitch % 4 != 0)
pitch = ((pitch/4) + 1) * 4;
System.Drawing.Bitmap bitmap = new Bitmap(mImageWidth, mImageHeight, pitch, System.Drawing.Imaging.PixelFormat.Format8bppIndexed, gch3.AddrOfPinnedObject());
gch3.Free();
if (pal == null)
{
System.Drawing.Imaging.ColorPalette cp = bitmap.Palette;
for (i = 0; i < cp.Entries.Length; ++i)
{
cp.Entries[i] = Color.FromArgb(i, i, i);
}
pal = cp;
}
bitmap.Palette = pal;
FirstImageDisplay.Image = bitmap;
//second image here
for (i = 0; i < frame.Length; ++i)
scaled[i] = (byte)(.5 * scaled[i]);
System.Runtime.InteropServices.GCHandle gch4 = System.Runtime.InteropServices.GCHandle.Alloc(scaled, System.Runtime.InteropServices.GCHandleType.Pinned);
int pitch1 = mImageWidth;
if (pitch1 % 4 != 0)
pitch1 = ((pitch1/4) + 1) * 4;
System.Drawing.Bitmap bitmap2 = new Bitmap(mImageWidth, mImageHeight, pitch, System.Drawing.Imaging.PixelFormat.Format8bppIndexed, gch4.AddrOfPinnedObject());
gch4.Free();
if (pal == null)
{
System.Drawing.Imaging.ColorPalette cp = bitmap.Palette;
for (i = 0; i < cp.Entries.Length; ++i)
{
cp.Entries[i] = Color.FromArgb(i, i, i);
}
pal = cp;
}
bitmap.Palette = pal;
SecondImageDisplay.Image = bitmap;
//end second image code
Я не знал, что Display.Image не создал собственную копию растрового изображения. Многое я не понимаю здесь (управляемая среда, закрепленная, проблема с выпуском указателя, ...). Я попытался изменить масштаб на новый массив, scaled1. Но это не работает. Не масштабируется1 в другом месте, чем масштабируется? Предложения? – DanG
@DanG Это зависит от того, как вы создаете 'scaled1' - если вы просто выполняете' scaled1 = scaled', вы просто назначаете новый указатель на ту же ячейку памяти. Вы должны использовать, например, 'new byte []' и скопировать данные, или, вернее, 'scaled1 = (byte []) scaled.Clone()'. Тем не менее, это по-прежнему плохая практика, как я описал выше - растровое изображение будет ссылаться на вашу ячейку памяти - и не знает о реорганизации GC управляемой памяти. Если вы не работаете с растровым изображением на короткое время, вы не хотите этого делать. – Luaan
Спасибо, это работает! Многому научиться здесь, читая много. Можете ли вы сказать несколько слов об управляемой v. Неуправляемой памяти? – DanG