Использование квадратного изображения на широкой плитке в приложении Магазина 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();
        }
    }
}
Другие вопросы по тегам