Изменение размера изображений в Silverlight 3 с использованием WriteableBitmap - PullRequest
5 голосов
/ 05 августа 2009

Это мой первый день с Silverlight. Я пытаюсь создать прототип приложения, которое (помимо других функций) должно иметь возможность изменять размеры предоставленных пользователем изображений. Он должен уметь обрабатывать и отображать несколько изображений с измененным размером одновременно. Наиболее очевидные подходы, которые я пробовал, кажутся «утечками» памяти в том смысле, что на оригинальные растровые изображения все еще ссылаются каким-то образом, что заставляет Silverlight выделять сотни мегабайт памяти через некоторое время. Я просто хочу иметь возможность загружать изображения по одному, изменять их размер и сохранять небольшие версии.

Если быть точным, я попробовал следующее:

  • Создание списка System.Windows.Controls.Image (и масштабирование их). Я не удивлен, что это не сработало.

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

  • Отображение растровых изображений в System.Windows.Media.Imaging.WriteableBitmap. Я ожидал, что это будет хорошо работать; Я предположил, что растровые изображения на самом деле просто нарисованы напрямую и ни на что не ссылаются. Тем не менее, потребление памяти указано иначе.

Вот фрагмент соответствующего фрагмента кода:

// create image source
Stream stream = file.OpenRead();
BitmapImage bmpImg = new BitmapImage();
bmpImg.SetSource(stream);
stream.Close();

// create temporary image from it
Image tmpImg = new Image();
tmpImg.Source = bmpImg;

// this is required by WriteableBitmap 
tmpImg.Measure(new Size(100, 100));
tmpImg.Arrange(new Rect(0, 0, 100, 100));

// prepare scaling to 100x100
ScaleTransform scaleTrans = new ScaleTransform();
double scale = (double)100 / (double)Math.Max(bmpImg.PixelHeight, bmpImg.PixelWidth);
scaleTrans.CenterX = 0;
scaleTrans.CenterY = 0;
scaleTrans.ScaleX = scale;
scaleTrans.ScaleY = scale;

// render
WriteableBitmap writeableBitmap = new WriteableBitmap(100, 100);
writeableBitmap.Render(tmpImg, scaleTrans);
writeableBitmap.Invalidate();

// final image
Image img = new Image();
img.Source = writeableBitmap;

Надеюсь, я не упускаю ничего глупого, но мне кажется, что все в порядке и делает правильные вещи (кроме проблемы с памятью). Также имейте в виду, что качество кода не должно быть качеством производства; это просто быстрый и грязный прототип.

Я заметил, что я не одинок; Я нашел вопросы, связанные с манипулированием изображениями в Silverlight. Мне также известен тот факт, что я мог бы использовать какую-нибудь стороннюю библиотеку, выполнять обработку на сервере или писать что-либо даже сам, но я удивлен, что Silverlight не предлагает каких-либо базовых функций управления изображениями. Это не является необычным требованием, если Silverlight позиционирует себя.

Ответы [ 2 ]

4 голосов
/ 28 апреля 2011

Вы смотрели на WriteableBitmapEx проект ? Это проект с открытым исходным кодом с множеством методов расширения для класса WriteableBitmap. Вот как вы изменяете размер:

BitmapImage image = new BitmapImage();
image.SetSource(dialog.File.OpenRead());

WriteableBitmap bitmap = new WriteableBitmap(image);
WriteableBitmap resizedBitmap = bitmap.Resize(500, 500, WriteableBitmapExtensions.Interpolation.Bilinear);

// For uploading
byte[] data = resizedBitmap.ToByteArray();
1 голос
/ 31 августа 2009

Я не знаю о специфике здесь, но если вы пропускаете ресурсы - вы можете посмотреть, какой из ваших объектов реализует интерфейс IDisposable. Я предполагаю, что классы Stream и Image реализуют этот интерфейс. И если они это сделают - вызов Dispose () для них (или включение их использования в оператор «Using») заставит их немедленно освободить свои ресурсы, вместо того, чтобы ждать, пока сборщик мусора начнет работать.

...