0

I'm trying to load a vector image in a zoomable ScrollViewer, works great on my laptop, but very slow on a tablet when zooming/unzooming. The UI is frozen during image rendering.

My image was converted from svg to xaml file with Inkscape. (~2,37 MB)

C#

public MainPage()
{
    this.InitializeComponent();

    this.Loaded += MainPage_Loaded;

}

async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    string fileContent;
    StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///Images/plan.xaml"));
    using (StreamReader sRead = new StreamReader(await file.OpenStreamForReadAsync()))
            fileContent = await sRead.ReadToEndAsync();

    var xamlRead = XamlReader.Load(fileContent) as Canvas;

    ImgMainGrid.Height = xamlRead.Height;
    ImgMainGrid.Width = xamlRead.Width;
    ImgMainGrid.Children.Add(xamlRead);
}

xaml

<ScrollViewer Grid.Row="1" x:Name="scrl" ZoomMode="Enabled" HorizontalScrollMode="Enabled" VerticalScrollMode="Enabled" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" MinZoomFactor="1">
     <Grid x:Name="ImgMainGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</ScrollViewer>

How can i render the Canvas in background ? (without blocking the UI). If it's not possible, how can i handle this rendering to add a ProgressBar while rendering ?

alvinmeimoun
  • 1,472
  • 1
  • 19
  • 38
  • Can you provide more of the C# code? Specifically, when are you calling it (in an event handler? etc) - will let us know whether you're running it on the UI thread or not, which is a common cause of delays like this. – rikkit Oct 06 '14 at 14:26
  • Edited first post to provide more C# code – alvinmeimoun Oct 06 '14 at 14:33
  • So my answer will be essentially the same as JaredPar's in this question: http://stackoverflow.com/questions/5395264/xamlreader-load-in-a-background-thread-is-it-possible - your tablet just isn't capable enough to do this operation (XamlReader.Load with a 2MB file) without lag. Unfortunately, XamlReader.Load must be used on the UI thread. You can try reducing the detail of the vector, or there might be a third party alternative for this problem out there somewhere. – rikkit Oct 06 '14 at 14:39
  • The problem is not on XamlReader.Load() call, it's on zoom. After zooming the image is blur and need to be rendered again, but during the new rendering the UI is frozen (i can't scroll on the blured image, touch another control, or zoom more). – alvinmeimoun Oct 06 '14 at 14:43
  • Ok. Well my answer is still the same, your tablet isn't capable of displaying that file in a Canvas to the same standard as your laptop. Canvas has to run on the UI thread. You can investigate a custom rendering method to improve performance, where your rendering pipeline is on a background thread. One way is to render a static image, then only re render after a zoom has completed. You can check Google Maps to see how this would look as they use a similar technique. – rikkit Oct 06 '14 at 14:48
  • Have you tried running it in the profiler to see what process is taking the most resources? – Nate Diamond Oct 06 '14 at 16:18

1 Answers1

0

This is not a real answer for this question, but a temporary solution.

First open svg file with inkscape and enlarge it to a big resolution (i tried with 3500*4000), and export to xaml. (This method will enlarge the image by keeping a small file size).

On C# code add xamlRead.CacheMode = new BitmapCache(); , this will render the image from vector to bitmap with the exported size.

In the end it 's like working with a very big PNG/JPEG image with a smaller file size. All other interests of use vector images are lost. But the result is fair.

alvinmeimoun
  • 1,472
  • 1
  • 19
  • 38