locked
working with WriteableBitmap RRS feed

  • Question

  • I am working with Window 8/WinRT and for reason WriteableBitmap is not working.  I looked the code from http://blog.mathieu-perrein.net/?tag=/WriteableBitmap

    I am just trying a look the result but I don't see anything. Here is my code.

    I would like to Blit some bitmap but how can I load WriteableBitmap as bitmap. Please look the syntax for Blit.

    void MainPage_Loaded(object sender, RoutedEventArgs e)
            {
                WriteableBitmap bitmap;
                WriteableBitmap writeableBmp = BitmapFactory.New(512, 512);
                writeableBmp.GetBitmapContext();

                // Load an image from the calling Assembly's resources only by passing the relative path
               // writeableBmp = BitmapFactory.New(1, 1).
                writeableBmp.Clear(Colors.Red);
                writeableBmp.DrawLine(1, 2, 30, 40, Colors.Green);

                Rect sourceRect = new Rect(0.0,0.0,194.0,224.0);
                // Blit a bitmap using the additive blend mode at P1(10, 10)
              //  writeableBmp.Blit(new Point(0, 0), bitmap, sourceRect, Colors.White, WriteableBitmapExtensions.BlendMode.Additive);

                writeableBmp.Invalidate();
                MyImage.Source = writeableBmp;

            }

    Any help will be very much appreciated.

    Agha Khan


    Agha Khan

    Sunday, January 5, 2014 7:08 AM

All replies

  • A WriteableBitmap is a BitmapSource and can be added to an image the same as you would use a BitmapImage (which is also a BitmapSource). Your MyImage.Source = writeableBmp; line is correct for that. If your question is how to load a WriteableBitmap from an image file then you can use the sample code in the BitmapSource.SetSourceAsync documentation, but change the BitmapImage for a WriteableBitmap (again: they are both BitmapSources and inherit the same behavior).

    I suspect that the problem is in creating the WriteableBitmap (in your BitmapFactory) or in the way the code draws it. WriteableBitmap doesn't have high level drawing constructs like "Clear", "DrawLine" or "Blit". You are probably getting these functions from the WriteableBitmapEx  library that you reference. What you have looks reasonable and I'd expect to see a Green line on a Red background, but I can't comment on if you are calling the WriteableBitmapEx functions correctly. You may want to check its codeplex site for help with WriteableBitmapEx  

    Note that the blog you refer to is for Windows Phone 7 and Silverlight. It is about a different version of WriteableBitmap than is available for Windows Store apps. While they are similar, the code in the blog may not apply exactly to Windows Store apps.

    --Rob

    Sunday, January 5, 2014 7:42 AM
    Moderator
  • Thanks Rob for replying.

    I understand the code I copied is from website is for not for WinRT, but it didn't complain at compile time and it should work. Here is the problem I am unable to change any functionality and screen is always black. The funny part is namespace of WriteableBitmapEx/WinRT is included.

    I am looking for sample which should show copying one image to another. Please guide me if you see any sample.

    BTW is there way to download a image without async?

    Best regards

    Agha


    Agha Khan

    Sunday, January 5, 2014 5:44 PM
  • Dear Rob:

    Just after replying I was able to configure myself how to show an image.

    WriteableBitmap writeableBmp = BitmapFactory.New(512, 512);
                using (writeableBmp.GetBitmapContext())
                {
                    // Load an image from the calling Assembly's resources only by passing the relative path
                    // writeableBmp = BitmapFactory.New(1, 1).
                    writeableBmp.Clear(Colors.Red);
                    writeableBmp.DrawLine(1, 2, 30, 40, Colors.Green);

                    Rect sourceRect = new Rect(0.0, 0.0, 194.0, 224.0);
                    // Blit a bitmap using the additive blend mode at P1(10, 10)
                  //  writeableBmp.Blit(new Point(0, 0), bitmap, sourceRect, Colors.White, WriteableBitmapExtensions.BlendMode.Additive);

                    writeableBmp.Invalidate();
                    MyImage.Source = writeableBmp;
                }

     This code works, but to Blit an image I need an image which should be already in the memory (Not a Async). How that can be done?

    Thanks for replying.

    Best regards

    Agha


    Agha Khan

    Sunday, January 5, 2014 6:19 PM
  • Why don't you want to use async? Async will help keep your app responsive and your users happy.

    That said, if your bitmap is small you can probably use SetSource rather than SetSourceAsync without causing problems.

    I cannot help with the WritableBitmapEx side of things.

    --Rob

    Sunday, January 5, 2014 7:01 PM
    Moderator
  • Dear Rob:

    Thanks for your reply.

    When I am going to Blits an image I should have that image in the memory.

    please guide me how can I use async when I want to use this function writeableBmp.Blit(new Point(0, 0), bitmap, sourceRect, Colors.White, WriteableBitmapExtensions.BlendMode.Additive);

    This question does not apply to writableBitmap but I should have bitmap on hand to use it. I don't think there a callback function which informs user that file has been loaded. As you suggested use SetSource but it also using stream which is again async type. Would you please kind enough to put some light how can we download files before we can use it. I have a ugly way to so, but I would like to know how you will do so?

    Best regards

    Agha Khan


    Agha Khan

    Sunday, January 5, 2014 8:25 PM
  • Do you mean you need to know how to get the bitmap object that you are trying to blit into your WriteableBitmap?

    That probably needs to be a WriteableBitmap loaded previously with SetSourceAsync.

    The HttpClient class can be used to download small files (use BackgroundTransfer for large ones). See the HttpClient sample  for examples.

    --Rob

    Tuesday, January 7, 2014 12:26 AM
    Moderator
  • Thanks for reply.
    I have figured it out, but first I have to create WriteableBitmap with stream. That I was able to do with this function.
    public static async Task<WriteableBitmap> GetImage(string source)
    {
            WriteableBitmap image = new WriteableBitmap(250, 250);
      string filename = string.Format("ms-appx:///Assets/{0}", source);
            var rass1 = RandomAccessStreamReference.CreateFromUri(new System.Uri(filename));
            IRandomAccessStream stream1 = await rass1.OpenReadAsync();

           //We initialize the bitmap with height and width, but the actual size will be reset after the FromStream method!
           image = await image.FromStream(stream1);
           return image;
    }
    This function works with no problem, but blank until it looks the streams. I don’t know how to stop to the my control’s constructor until files are available.  
    I tried something like this.
    Task task = GetImage(“Nut”);
    Task.Wait();
    But it halts the application.
    You may have better thoughts.
    Best regards
    Agha Khan


    Agha Khan

    Tuesday, January 7, 2014 12:52 AM
  • You need to use the async system. You cannot block the UI thread without severely irritating your users. Asynchronous programming in .NET (Windows Store apps using C#/VB/C++ and XAML) will help explain it.

    To call your GetImage method asynchronously do:

    WriteableBitmap nutImage = await GetImage("nut");
    
    --Rob

    Tuesday, January 7, 2014 1:30 AM
    Moderator
  • Thanks.

    protected async override void OnApplyTemplate()

    {

         WriteableBitmap nutImage = await GetImage("Nuts.png");

    }

    It blocked the application. It is waiting and never come back.

    Best regards

    Agha


    Agha Khan

    Tuesday, January 7, 2014 1:39 AM
  • Dear Rob:

    Update.

    if I use that function outside from OnApplyTemplate then time is so short the application was unable to down the stream files (and no image foe me)  which implies I am not able to use outside and inside it blocks the application.

    There must be some other way to delay OnApplyTemplate but I don't know.

    Well if I load the stream from App.cs then it works, because I have plenty of time to download (before my UI shows) stream file. I don't like that way. There must me some other ways. I am still looking.

    Agha Khan 


    Agha Khan

    Tuesday, January 7, 2014 1:55 AM
  • You'll need to provide more specific information if you need more detailed help. Can you provide a minimal sample?

    You may need to move your image handling out of OnApplyTemplate. Use a place-holder initially and then fill in the bitmaps as they are generated.

    --Rob

    Saturday, January 11, 2014 12:49 AM
    Moderator