Как скопировать и изменить размер изображения в Windows 10 UWP

Я использовал код с http://www.codeproject.com/Tips/552141/Csharp-Image-resize-convert-and-save для программного изменения размера изображений. Однако в этом проекте используются библиотеки System.Drawing, недоступные для приложений Windows 10.

Вместо этого я попытался использовать класс BitmapImage из Windows.UI.Xaml.Media.Imaging, но, похоже, он не предлагает функциональности, которая была найдена в System.Drawing..

Удалось ли кому-нибудь изменить размер (уменьшить) изображения в Windows 10? Мое приложение будет обрабатывать изображения из нескольких источников в разных форматах/размерах, и я пытаюсь изменить размер фактических изображений, чтобы сэкономить место, а не просто позволить приложению изменить его размер, чтобы он соответствовал Image, в котором он отображается.

ИЗМЕНИТЬ

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

public static BitmapImage ResizedImage(BitmapImage sourceImage, int maxWidth, int maxHeight)
{
    var origHeight = sourceImage.PixelHeight;
    var origWidth = sourceImage.PixelWidth;
    var ratioX = maxWidth/(float) origWidth;
    var ratioY = maxHeight/(float) origHeight;
    var ratio = Math.Min(ratioX, ratioY);
    var newHeight = (int) (origHeight * ratio);
    var newWidth = (int) (origWidth * ratio);

    sourceImage.DecodePixelWidth = newWidth;
    sourceImage.DecodePixelHeight = newHeight;

    return sourceImage;
}

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

Вот снимок этого в действии: скриншот изображения с измененным размером


person dub stylee    schedule 15.03.2016    source источник
comment
Вводящее в заблуждение название, ОП. У вас есть способ изменить размер изображения, что вы действительно хотите сделать, это создать копию исходного изображения, изменить размер копии, а затем вернуть копию.   -  person Brian Driscoll    schedule 15.03.2016
comment
@BrianDriscoll Я опубликовал вопрос до редактирования. Редактирование добавило код для изменения размера исходного изображения. Я бы опубликовал это как ответ, но этого еще недостаточно. Но мне нравится новое название. Спасибо.   -  person dub stylee    schedule 16.03.2016
comment
Вы можете просто создать константу изображения? Или частная собственность, вы можете просто сослаться на исходную копию изображения и использовать ту же функцию?   -  person aguertin    schedule 16.03.2016
comment
Поскольку мне не нужно сохранять исходные данные изображения нетронутыми, все в порядке, как сейчас. Я просто думаю о будущем обобщении, возможно, я захочу вернуть копию оригинала BitmapImage, а не изменять оригинал.   -  person dub stylee    schedule 16.03.2016


Ответы (1)


Я могу захотеть вернуть копию оригинала BitmapImage, а не изменять оригинал.

Не существует хорошего способа прямого копирования BitmapImage, но мы можем повторно использовать StorageFile несколько раз.

Если вы просто хотите выбрать изображение, показать его и в то же время показать изображение с измененным размером исходного изображения, вы можете передать параметр StorageFile as следующим образом:

public static async Task<BitmapImage> ResizedImage(StorageFile ImageFile, int maxWidth, int maxHeight)
{
    IRandomAccessStream inputstream = await ImageFile.OpenReadAsync();
    BitmapImage sourceImage = new BitmapImage();
    sourceImage.SetSource(inputstream);
    var origHeight = sourceImage.PixelHeight;
    var origWidth = sourceImage.PixelWidth;
    var ratioX = maxWidth / (float)origWidth;
    var ratioY = maxHeight / (float)origHeight;
    var ratio = Math.Min(ratioX, ratioY);
    var newHeight = (int)(origHeight * ratio);
    var newWidth = (int)(origWidth * ratio);

    sourceImage.DecodePixelWidth = newWidth;
    sourceImage.DecodePixelHeight = newHeight;

    return sourceImage;
}

В этом случае вам просто нужно вызвать эту задачу и показать измененное изображение следующим образом:

smallImage.Source = await ResizedImage(file, 250, 250);

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

person Grace Feng    schedule 16.03.2016
comment
Это превосходно, спасибо Грейс. Есть ли способ получить BitmapImage или IRandomAccessStream в WriteableBitmap или RenderTargetBitmap для кодирования в строку base64? Я могу сделать StorageFile напрямую, но поскольку измененное изображение не является StorageFile, мне нужно вернуть его в другой тип данных для кодирования. - person dub stylee; 16.03.2016
comment
В итоге я изменил весь процесс на использование WriteableBitmap вместо BitmapImage, чтобы у меня было изображение в необходимом формате для кодирования в base64. Мне все еще нужно создать BitmapImage внутри функции ResizedImage, чтобы получить исходные размеры, но, по крайней мере, это работает :) - person dub stylee; 16.03.2016
comment
@dubstylee, вы все делаете правильно, я не могу найти способ преобразовать BitmapImage в строку 64base. Чтобы превратить IRandomAccessStream в WriteableBitmap, вы можете использовать BitmapDecoder, но я думаю, вы уже знаете это. - person Grace Feng; 17.03.2016