2

Working wth live tiles in my Windows Phone 7 app and it's working quite okay.

I'm now trying to create a dynamic live tile and I can't get the background image to show up. When using the code below I only get a black tile. The text I add is shown but not the background image. Image "Build action" is set to "Content".

Any ideas?

StackPanel sp = new StackPanel();
sp.Height = 173;
sp.Width = 173;

string fileName = "tile.jpg";
BitmapImage image = new BitmapImage(new Uri(fileName, UriKind.Relative));
ImageBrush brush = new ImageBrush();
brush.ImageSource = image;
sp.Background = brush;

sp.Measure(new Size(173, 173));
sp.Arrange(new Rect(0, 0, 173, 173));
sp.UpdateLayout();
WriteableBitmap wbm = new WriteableBitmap(173, 173);
wbm.Render(sp, null);
wbm.Invalidate();
John
  • 681
  • 1
  • 8
  • 20

3 Answers3

3

I also had problems using BitmapImage and still don't know how to solve it. But I found a workaround using WriteableBitmap:

        // grid is container for image and text
        Grid grid = new Grid();

        // load your image
        StreamResourceInfo info = Application.GetResourceStream(new Uri(filename, UriKind.Relative));
        // create source bitmap for Image control (image is assumed to be alread 173x173)
        WriteableBitmap wbmp2 = new WriteableBitmap(1,1);
        wbmp2.SetSource(info.Stream);
        Image img = new Image();
        img.Source = wbmp2;
        // add Image to Grid
        grid.Children.Add(img);

        TextBlock text = new TextBlock() { FontSize = (double)Resources["PhoneFontSizeExtraLarge"], Foreground = new SolidColorBrush(Colors.White) };
        // your text goes here:
        text.Text = "Hello\nWorld";
        grid.Children.Add(text);

        // this is our final image containing custom text and image
        WriteableBitmap wbmp = new WriteableBitmap(173, 173);

        // now render everything - this image can be used as background for tile
        wbmp.Render(grid, null);
        wbmp.Invalidate();
Heinrich Ulbricht
  • 10,064
  • 4
  • 54
  • 85
  • Thanks Heinrich! Works just fine! Has it ever happened with your code that the image is not fully loaded and therefore not beeing shown? I read about it but that might not be an issue here, right? – John Nov 07 '11 at 06:15
  • It has happend and I suspect that this is an issue here as well. Sometimes setting `CreateOptions` (http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapcreateoptions%28v=VS.95%29.aspx) to `None` helped loading the image immediately, but it doesn't seem to work here. So I'd really like to try something like `BitmapImage.ForceLoadingNow()` but I couldn't find the appropriate method. – Heinrich Ulbricht Nov 07 '11 at 07:24
  • Aha okay, that's bad. Does it happen often? Is it the wbmp2 that fails or is it the entire layout (wbmp) for the live tile that is not beeing shown? Anyone else that can help us out here? – John Nov 07 '11 at 07:40
  • It just happens with `BitmapImage`, so no worries about the code above. It intentionally doesn't use it. With "here as well" meant "here in your original code using BitmapImage", not "here above" ;) – Heinrich Ulbricht Nov 07 '11 at 07:44
  • So you mean that my original code is where you noticed problems, but not in your code? – John Nov 07 '11 at 07:45
  • Exactly! My mental context was set to your question when writing "here". Sorry for the confusion. – Heinrich Ulbricht Nov 07 '11 at 07:46
  • Haha, alright! Sorry for not getting that :) Thanks again for your help! – John Nov 07 '11 at 07:47
2

Try this - it worked for me:

Uri uri = new Uri("tile.jpg", UriKind.Relative);
StreamResourceInfo sri = Application.GetResourceStream(uri);

WriteableBitmap wbm = new WriteableBitmap(173, 173);
wbm.SetSource(sri.Stream);

using (var stream = IsolatedStorageFile.GetUserStoreForApplication().CreateFile("/Shared/ShellContent/tile.png"))
{
    wbm.SaveJpeg(stream, 173, 173, 0, 100);
}

var data = new StandardTileData();
data.BackgroundImage = new Uri("isostore:/Shared/ShellContent/tile.png", UriKind.Absolute);
data.Title = "updated image";

var tile = ShellTile.ActiveTiles.First();
tile.Update(data);
Chris Koenig
  • 2,736
  • 18
  • 17
  • Thank you Chris for your help! I ended up testing the other solution below since it looked a bit more like my code and I felt more familiar with it (I'm a happy beginner :) and struggeling to get a grip of everything). – John Nov 07 '11 at 06:14
0

I think the problem is the image is being loaded asynchronously, and therefore not available. I succeeded with this code:

BitmapImage bmi = new BitmapImage();
bmi.CreateOptions = BitmapCreateOptions.None;
StreamResourceInfo streamInfo = 
     Framework.App.GetResourceStream(new Uri(@"images\img.png", 
          UriKind.Relative));
bmi.SetSource(streamInfo.Stream);
imgctl.Source = bmi;

However, I'm still trying to get it to work when loaded from Xaml thus:

<Image  HorizontalAlignment="Center" Width="173" Height="89" x:Name="imgctl" 
    Source="/images/lowsunrise.png"/>

In that case, the image is never loaded, and none of the events fire, probably because it's not connected to the visual tree, and therefore won't be rendered.

Anthony Wieser
  • 4,351
  • 1
  • 23
  • 25