0

I have referred the below thread for combing multiple images as single image in uwp. Merging multiple Images

But the image is not properly converted from Uri to bitmap images for the tiles downloaded from below link

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

Devi M
  • 39
  • 5
  • Why are you doing this at all, instead of putting multiple Image elements in a Grid? – Clemens Jun 26 '18 at 09:03
  • In my case I want to add and remove images based on the pinching level(zoom level). If I directly use image control, I am getting flickering effect while adding and removing the images. That's why I want to combine multiple images as single one – Devi M Jun 26 '18 at 09:04
  • Put multiple Grids on top of each other. And did you take a look at [this](https://github.com/ClemensFischer/XAML-Map-Control)? It smoothly blends zoom level layers. – Clemens Jun 26 '18 at 09:06
  • Could not run the sample in that link – Devi M Jun 26 '18 at 09:51
  • But you wouldn't tell why? What exactly didn't work with it? – Clemens Jun 26 '18 at 10:42
  • I could run only the WPF sample. I am getting nuget restoring error for Microsoft.NetCore.UniversalWindowsPlatform. Also, I have debugged WPF application. I could not understand why the TileGrid has been refreshed every time – Devi M Jun 26 '18 at 12:22
  • "refreshed every time" - not sure what you mean with that. It is refreshed whenever necessary. – Clemens Jun 26 '18 at 12:30
  • All the images are added child for MapTileLayer and TileGrid is not used anywhere so far, I have debugged and I dint understand how the flickering effect has been overcome everytime when clearing the children of MapTileLayer – Devi M Jun 26 '18 at 12:35
  • Could u explain, how the flickering effect has been avoided when moving from one zoom level to another level? – Devi M Jun 26 '18 at 12:36
  • That's done by animating the Opacity property of the Image elements that show the map tiles. – Clemens Jun 26 '18 at 13:43
  • For the NuGet restore error, you could just open Package Manager for both the MapControl.UWP and UniversalApp projects, and update Microsoft.NetCore.UniversalWindowsPlatform to the latest version. – Clemens Jun 26 '18 at 14:23
  • @clemens if possible, could you provide any simple sample for animating the grid children with opacity , when dynamically removing or adding child in to it? – Devi M Jul 02 '18 at 03:52

1 Answers1

0

I found your previous two threads:

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

How to combine multiple image as single image in UWP

They all aimed to avoid the flickering effect. As I comment in your second thread, the flickering effect is caused by you change the images's source in a short time, if you want to avoid it, you can use the animation to change the images with a progress. Here is a example to use the DoubleAnimation Storyboard to animate Opacity property of the Images stackpanel base on your first thread sample:

MainPage.xaml: I create two storyboard to make the images stackpanel disappear or display and give the disappearStoryboard a disappearStoryboard_Completed event handler.

<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: I change the Images' resource in the disappearStoryboard 's disappearStoryboard_Completed event handler.

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }
    bool replaceButtonClicked, replaceCustomButtonClicked, replaceTileButtonClicked;

    private void replace_Click(object sender, RoutedEventArgs e)
    {
        replaceButtonClicked = true;
        disappearStoryboard.Begin();
    }

    private void replaceCustom_Click(object sender, RoutedEventArgs e)
    {
        replaceCustomButtonClicked = true;
        disappearStoryboard.Begin();
    }

    private void replaceTile_Click(object sender, RoutedEventArgs e)
    {
        replaceTileButtonClicked = true;
        disappearStoryboard.Begin();
    }

    private void disappearStoryboard_Completed(object sender, object e)
    {
        if (replaceButtonClicked)
        {
            image1.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM200.png",
         UriKind.RelativeOrAbsolute));
            image2.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM201.png",
              UriKind.RelativeOrAbsolute));
            image3.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM202.png",
              UriKind.RelativeOrAbsolute));
            image4.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM203.png",
              UriKind.RelativeOrAbsolute));
            image5.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM210.png",
              UriKind.RelativeOrAbsolute));
            image6.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM211.png",
              UriKind.RelativeOrAbsolute));
            image7.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM212.png",
              UriKind.RelativeOrAbsolute));
            image8.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM213.png",
              UriKind.RelativeOrAbsolute));
            image9.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM220.png",
              UriKind.RelativeOrAbsolute));
            image10.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM221.png",
              UriKind.RelativeOrAbsolute));
            image11.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM222.png",
              UriKind.RelativeOrAbsolute));
            image12.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM223.png",
              UriKind.RelativeOrAbsolute));
            replaceButtonClicked = false;
        }
        if (replaceCustomButtonClicked)
        {
            image1.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom200.png",
         UriKind.RelativeOrAbsolute));
            image2.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom201.png",
              UriKind.RelativeOrAbsolute));
            image3.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom202.png",
              UriKind.RelativeOrAbsolute));
            image4.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom203.png",
              UriKind.RelativeOrAbsolute));
            image5.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom210.png",
              UriKind.RelativeOrAbsolute));
            image6.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom211.png",
              UriKind.RelativeOrAbsolute));
            image7.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom212.png",
              UriKind.RelativeOrAbsolute));
            image8.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom213.png",
              UriKind.RelativeOrAbsolute));
            image9.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom220.png",
              UriKind.RelativeOrAbsolute));
            image10.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom221.png",
              UriKind.RelativeOrAbsolute));
            image11.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom222.png",
              UriKind.RelativeOrAbsolute));
            image12.Source = new BitmapImage(new Uri("ms-appx:///Assets/custom223.png",
              UriKind.RelativeOrAbsolute));
            replaceCustomButtonClicked = false;
        }
        if (replaceTileButtonClicked)
        {
            image1.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM300.png",
         UriKind.RelativeOrAbsolute));
            image2.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM301.png",
              UriKind.RelativeOrAbsolute));
            image3.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM302.png",
              UriKind.RelativeOrAbsolute));
            image4.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM303.png",
              UriKind.RelativeOrAbsolute));
            image5.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM304.png",
              UriKind.RelativeOrAbsolute));
            image6.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM305.png",
              UriKind.RelativeOrAbsolute));
            image7.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM306.png",
              UriKind.RelativeOrAbsolute));
            image8.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM301.png",
              UriKind.RelativeOrAbsolute));
            image9.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM302.png",
              UriKind.RelativeOrAbsolute));
            image10.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM303.png",
              UriKind.RelativeOrAbsolute));
            image11.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM310.png",
              UriKind.RelativeOrAbsolute));
            image12.Source = new BitmapImage(new Uri("ms-appx:///Assets/OSM311.png",
              UriKind.RelativeOrAbsolute));
            replaceTileButtonClicked = false;
        }
        displayStoryboard.Begin();
    }

}
Breeze Liu - MSFT
  • 3,734
  • 1
  • 10
  • 13