Как преобразовать значок окна в BitmapImage

Я пытаюсь поблагодарить эту ветку Convert ImageSource to BitmapImage - WPF to преобразовать мое окно icon типа ImageSource в BitmapImage :

var bi = _window.Icon as BitmapImage;

Проблема в том, что приведение не происходит (bi имеет значение null после выполнения этой строки), и я уверен, что _window.Icon не равно null, может ли кто-нибудь сказать мне, почему это преобразование не происходит?

Обновление:

Хотя в документации Visual Studio говорится, что Window.Icon имеет тип ImageSource, но отладчик говорит, что это System.Windows.Media.Imaging.BitmapFrameDecode

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

var bi = (BitmapImage) _window.Icon;

Я получаю следующее исключение:

Дополнительная информация: невозможно привести объект типа «System.Windows.Media.Imaging.BitmapFrameDecode» к типу «System.Windows.Media.Imaging.BitmapImage».


person AymenDaoudi    schedule 21.07.2014    source источник
comment
Зачем нужно делать это преобразование? В большинстве ситуаций должно быть достаточно прямого использования ImageSource.   -  person Clemens    schedule 22.07.2014
comment
Re: ваше редактирование, здесь нет противоречия ... ImageSource - это абстрактный класс, поэтому значок никогда не является экземпляром ImageSource; BitmapFrameDecode является подклассом ImageSource, поэтому это допустимое значение свойства. Однако это не подкласс BitmapImage, поэтому приведение не выполняется.   -  person Thomas Levesque    schedule 22.07.2014


Ответы (2)


Проблема в том, что приведение не происходит (bi имеет значение null после выполнения этой строки), и я уверен, что _window.Icon не равен нулю

Это не ноль, но, вероятно, это не BitmapImage. Window.Icon относится к типу ImageSource, от которого происходит BitmapImage. Когда вы устанавливаете значок в XAML, тип изображения обычно System.Windows.Media.Imaging.BitmapFrameDecode, который является внутренним классом, производным от BitmapFrame; так что это не BitmapImage, поэтому бросок не работает.


РЕДАКТИРОВАТЬ: если вам просто нужно преобразовать значок в System.Drawing.Bitmap, вам не нужен BitmapImage; BitmapSource достаточно.

var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)_window.Icon));
using (var stream = new MemoryStream()))
{
    encoder.Save(stream);
    stream.Position = 0; // rewind the stream
    var bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromStream(stream);
    var icon = System.Drawing.Icon.FromHandle(bitmap.GetHicon());
}
person Thomas Levesque    schedule 21.07.2014
comment
Возможно, стоит отметить, что существует BitmapSource как общий базовый класс BitmapImage и BitmapFrame (и, следовательно, BitmapFrameDecode), который имеет общие свойства растрового изображения, такие как PixelWidth, PixelHeight, DpiX, DpiY и т. д. - person Clemens; 22.07.2014
comment
@ Клеменс, хорошая мысль. В зависимости от того, что действительно нужно OP, может быть достаточно приведения к BitmapSource. - person Thomas Levesque; 22.07.2014
comment
@Thomas: Действительно, я обновил свой пост, поэтому не могли бы вы показать мне, как я могу правильно выполнить преобразование, цель этого - преобразовать значок окна в объект System.Drawing.Icon, поэтому я должен пройти через: ImageSource - › BitmapImage -> Bitmap, чем я сохраняю растровое изображение как значок, выполнив: Bitmap.Save(Path, ImageFormat.Icon). Если моя процедура неверна, пожалуйста, покажите мне, как мне действовать, спасибо. - person AymenDaoudi; 22.07.2014
comment
@ThomasLevesque: спасибо, это абсолютно работает, но есть ли способ сделать это без сохранения _window.Icon, как в using (var stream = File.OpenWrite("icon.png")) encoder.Save(stream);, я имею в виду, можно ли программно перейти напрямую от (BitmapSource)_window.Icon к Bitmap, а затем к System.Drawing.Icon без прохождения этой операции ввода-вывода - person AymenDaoudi; 22.07.2014
comment
@AymenDaoudi, конечно, вы можете использовать MemoryStream вместо FileStream и загружать растровое изображение из этого потока, а не из файла (Image.FromStream) - person Thomas Levesque; 22.07.2014
comment
@AymenDaoudi, я отредактировал свой ответ, чтобы показать, как вместо этого использовать MemoryStream - person Thomas Levesque; 22.07.2014
comment
@AymenDaoudi Просто примечание. Ответить на этот вопрос было бы намного проще, если бы вы с самого начала сказали нам, что хотите перейти на System.Drawing.Icon. - person Clemens; 22.07.2014
comment
@Clemens Действительно, просто я избегал дублирования одних и тех же других вопросов. - person AymenDaoudi; 22.07.2014

Понятия не имею, почему именно вам нужно привести к BitmapImage. В любой практической ситуации вместо этого должно быть достаточно приведения к BitmapSource (который является общим базовым классом для BitmapImage и BitmapFrame):

var bitmap = _window.Icon as BitmapSource;

BitmapSource предоставляет все соответствующие свойства растрового изображения, такие как PixelWidth, PixelHeigth, DpiX, DpiY, Format и т. д.

person Clemens    schedule 21.07.2014