Использование квадратного изображения на широкой плитке в приложении Магазина Windows
В моем приложении я хочу реализовать вторичные листы, чтобы пользователи могли напрямую получать доступ к определенным разделам моего приложения и показывать информацию, относящуюся к конкретным разделам, на этом листе.
Для изображения мозаики я хочу использовать значок раздела, к которому будет получен прямой доступ, но у меня есть доступ только к изображениям квадратного размера, которые загружаются непосредственно по веб-ссылке (при создании плитки). Поскольку у меня нет изображений для широких плиток, я попытался заполнить их прозрачными границами, чтобы создать широкую плитку. Я использовал библиотеку WritableBitmapEx, но мой код вызывает AccessViolationException.
StorageFile file = await ApplicationData.Current.TemporaryFolder.GetFileAsync(tempFileName);
IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
WriteableBitmap bitmap = new WriteableBitmap(150, 150);
await bitmap.SetSourceAsync(fileStream);
WriteableBitmap bitmapDummy = BitmapFactory.New(310, 150);
using (bitmapDummy.GetBitmapContext())
{
using (bitmap.GetBitmapContext())
{
bitmapDummy.Blit(new Rect(80.0, 0.0, 150, 150), bitmap, new Rect(0.0, 0.0, 150, 150), WriteableBitmapExtensions.BlendMode.None);
}
}
исключение происходит на bitmap.GetBitmapContext()
поэтому я не могу создать изображение.
Здесь я пытаюсь создать пустое широкое изображение плитки и поместить квадратное изображение плитки в середину.
Также в конце я хочу преобразовать изображение в прозрачный PNG, но это еще одна проблема, так как я пока не могу понять, как создать растровое изображение.
Спасибо за вашу помощь заранее.
1 ответ
Я нашел решение здесь. Кажется, что изображение не было загружено в WriteableBitmap до того, как я попытался получить к нему доступ, следовательно, возникла исключительная ситуация AccessViolationException. Так что вместо
WriteableBitmap bitmap = new WriteableBitmap(150, 150);
await bitmap.SetSourceAsync(fileStream);
Я начал использовать,
WriteableBitmap bitmap = await BitmapFactory.New(1, 1).FromStream(fileStream);
и проблема теперь решена.
Полный код, который изменяет размеры и дополняет квадратное изображение для тех, кто находит этот вопрос, приведен ниже.
public static async Task PadPngImage(StorageFile inputFile, StorageFile outputFile, uint width, uint height, uint boundingBoxWidth, uint boundingBoxHeight)
{
// Resize the input image
StorageFile temporaryFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("PadImageTemporaryFile.png", CreationCollisionOption.ReplaceExisting);
await ResizeImage(inputFile, temporaryFile, width, height);
// Create a stream linked to resized image
using (IRandomAccessStream temporaryFileStream = await temporaryFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
WriteableBitmap bitmap = await BitmapFactory.New(1, 1).FromStream(temporaryFileStream);
// Create an empty image with specified bounding dimentions
WriteableBitmap bitmapDummy = BitmapFactory.New((int)boundingBoxWidth, (int)boundingBoxHeight);
using (bitmapDummy.GetBitmapContext())
{
using (bitmap.GetBitmapContext())
{
// Calculate position of the image
Rect center = new Rect((boundingBoxWidth - width) / 2, (boundingBoxHeight - height) / 2, width, height);
bitmapDummy.Blit(center, bitmap, new Rect(0.0, 0.0, width, height), WriteableBitmapExtensions.BlendMode.None);
}
}
using(IRandomAccessStream stream = await outputFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
await bitmapDummy.ToStream(stream, BitmapEncoder.PngEncoderId);
}
}
}
public static async Task ResizeImage(StorageFile inputFile, StorageFile outputFile, uint newWidth, uint newHeight)
{
// Input Stream & Decoder
using (IRandomAccessStream fileStream = await inputFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
// Output Stream & Encoder
using (IRandomAccessStream stream = await outputFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(stream, decoder);
// Scale the bitmap image
encoder.BitmapTransform.ScaledWidth = newWidth;
encoder.BitmapTransform.ScaledHeight = newHeight;
encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
await encoder.FlushAsync();
}
}
}