无法在UWP中将图像从Uri转换为位图图像

时间:2018-06-26 08:47:53

标签: c# bitmap uwp image-conversion

在uwp中,我引用了以下线程将多个图像组合为单个图像。 Merging multiple Images

但是对于从下面的链接下载的图块,该图像无法从Uri正确转换为位图图像

https://a.tile.openstreetmap.org/0/0/0.png

  public MainPage()
        {
            this.InitializeComponent();
            MergeImages();
        }

        async void MergeImages()
        {
            byte[] Canvas = new byte[512 * 512 * 4];

                Windows.Storage.Streams.IRandomAccessStream random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(
                    new Uri("https://a.tile.openstreetmap.org/1/0/0.png",UriKind.RelativeOrAbsolute)).OpenReadAsync();
                Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(random);
                Windows.Graphics.Imaging.PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
                byte[] tileImage = pixelData.DetachPixelData();
                Canvas = PutOnCanvas(Canvas, tileImage, 0,
                    0, 256, 256, 512);

            InMemoryRandomAccessStream memStream = new InMemoryRandomAccessStream();
            var encoder = await BitmapEncoder.CreateAsync(Windows.Graphics.Imaging.BitmapEncoder.PngEncoderId, memStream);
            encoder.SetPixelData(
                Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8,
                Windows.Graphics.Imaging.BitmapAlphaMode.Straight,
               512, // pixel width
               512, // pixel height
                96, // horizontal DPI
                96, // vertical DPI
                Canvas);

            try
            {
                await encoder.FlushAsync();
                var bitmapImage = new BitmapImage();

                await bitmapImage.SetSourceAsync(memStream);
                image.Source = bitmapImage;
            }
            catch { }
            memStream.Dispose();
        }

        byte[] PutOnCanvas(byte[] Canvas, byte[] Image, uint x, uint y, uint imageheight, uint imagewidth, uint CanvasWidth)
        {
            for (uint row = y; row < y + imageheight; row++)
                for (uint col = x; col < x + imagewidth; col++)
                    for (int i = 0; i < 4; i++)
                        Canvas[(row * CanvasWidth + col) * 4 + i] = Image[((row - y) * imagewidth + (col - x)) * 4 + i];

            return Canvas;
        }

Sample

Actual Output:

Expected output

1 个答案:

答案 0 :(得分:0)

我找到了您之前的两个主题:

How to avoid the flickering effect when dynamically changes the image source in uwp

How to combine multiple image as single image in UWP

它们都旨在避免闪烁效果。当我在第二个线程中评论时,闪烁效果是由您在短时间内更改图像的来源引起的,如果要避免它,可以使用动画来逐步更改图像。下面是一个示例,该示例基于您的第一个线程sample,使用DoubleAnimation故事板来为Images堆栈面板的Opacity属性设置动画:

MainPage.xaml:我创建了两个情节提要,以使图像堆栈面板消失或显示,并为disappearStoryboard提供disappearStoryboard_Completed事件处理程序。

<Page.Resources>
    <Storyboard x:Name="disappearStoryboard" Completed="disappearStoryboard_Completed">
        <DoubleAnimation
        Storyboard.TargetName="RootStackPanel"
        Storyboard.TargetProperty="Opacity"
        From="1.0" To="0.0" Duration="0:0:1"/>
    </Storyboard>

    <Storyboard x:Name="displayStoryboard">
        <DoubleAnimation
        Storyboard.TargetName="RootStackPanel"
        Storyboard.TargetProperty="Opacity"
        From="0.0" To="1.0" Duration="0:0:1"/>
    </Storyboard>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel Name="RootStackPanel">
        <StackPanel Orientation="Horizontal">
            <Image x:Name="image1" Height="200" Width="200" Source="ms-appx:///Assets/custom200.png"/>
            <Image x:Name="image2" Height="200" Width="200" Source="ms-appx:///Assets/custom201.png"/>
            <Image x:Name="image3" Height="200" Width="200" Source="ms-appx:///Assets/custom202.png"/>
            <Image x:Name="image4" Height="200" Width="200" Source="ms-appx:///Assets/custom203.png"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image x:Name="image5" Height="200" Width="200" Source="ms-appx:///Assets/custom210.png"/>
            <Image x:Name="image6" Height="200" Width="200" Source="ms-appx:///Assets/custom211.png"/>
            <Image x:Name="image7" Height="200" Width="200" Source="ms-appx:///Assets/custom212.png"/>
            <Image x:Name="image8" Height="200" Width="200" Source="ms-appx:///Assets/custom213.png"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Image x:Name="image9"  Height="200" Width="200" Source="ms-appx:///Assets/custom220.png"/>
            <Image x:Name="image10" Height="200" Width="200" Source="ms-appx:///Assets/custom221.png"/>
            <Image x:Name="image11" Height="200" Width="200" Source="ms-appx:///Assets/custom222.png"/>
            <Image x:Name="image12" Height="200" Width="200" Source="ms-appx:///Assets/custom223.png"/>
        </StackPanel>
    </StackPanel>
    <StackPanel Grid.Row="1" Orientation="Horizontal">
        <Button Height="50" Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"
                Content="ReplaceCustom" x:Name="replaceCustom" Click="replaceCustom_Click" Margin="5"/>

        <Button Height="50" Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"
                Content="Replace OSM" x:Name="replaceOSM" Click="replace_Click" Margin="5"/>

        <Button Height="50" Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"
                Content="Replace Tile" x:Name="replaceTile" Click="replaceTile_Click" Margin="5"/>
    </StackPanel>
</Grid>

MainPage.xaml.cs:我在disappearStoryboard的{​​{1}}事件处理程序中更改了图像的资源。

disappearStoryboard_Completed