Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save BitmapImage to File

Tags:

I am working on a program that downloads images from a URL to a bitmapimageand displays it. Next I try to save the bitmapimage to the harddrive using jpegbitmapencoder. The file is successfully created but the actual jpeg image is empty or 1 black pixel.

public Guid SavePhoto(string istrImagePath) {     ImagePath = istrImagePath;      BitmapImage objImage = new BitmapImage(         new Uri(istrImagePath, UriKind.RelativeOrAbsolute));     PictureDisplayed.Source = objImage;     savedCreationObject = objImage;      Guid photoID = System.Guid.NewGuid();     string photolocation = photoID.ToString() + ".jpg";  //file name      JpegBitmapEncoder encoder = new JpegBitmapEncoder();     encoder.Frames.Add(BitmapFrame.Create(objImage));      using (FileStream filestream = new FileStream(photolocation, FileMode.Create))     {         encoder.Save(filestream);     }      return photoID; } 

This is the function that saves and displays the photo. The photo is displayed correctly but again when it is saved I get an empty jpeg or 1 black pixel.

like image 552
Ben Unsworth Avatar asked Nov 12 '10 03:11

Ben Unsworth


1 Answers

When you create your BitmapImage from a Uri, time is required to download the image.

If you check the following property, the value will likely be TRUE

objImage.IsDownloading 

As such, you much attach a listener to the DownloadCompleted event handler and move all processing to that EventHandler.

objImage.DownloadCompleted += objImage_DownloadCompleted; 

Where that handler will look something like:

private void objImage_DownloadCompleted(object sender, EventArgs e) {   JpegBitmapEncoder encoder = new JpegBitmapEncoder();   Guid photoID = System.Guid.NewGuid();   String photolocation = photoID.ToString() + ".jpg";  //file name     encoder.Frames.Add(BitmapFrame.Create((BitmapImage)sender));    using (var filestream = new FileStream(photolocation, FileMode.Create))     encoder.Save(filestream); }  

You will likely also want to add another EventHandler for DownloadFailed in order to gracefully handle any error cases.

Edit

Added full sample class based on Ben's comment:

public partial class MainWindow : Window {   public MainWindow()   {     InitializeComponent();      SavePhoto("http://www.google.ca/intl/en_com/images/srpr/logo1w.png");   }    public void SavePhoto(string istrImagePath)   {     BitmapImage objImage = new BitmapImage(new Uri(istrImagePath, UriKind.RelativeOrAbsolute));      objImage.DownloadCompleted += objImage_DownloadCompleted;   }    private void objImage_DownloadCompleted(object sender, EventArgs e)   {     JpegBitmapEncoder encoder = new JpegBitmapEncoder();     Guid photoID = System.Guid.NewGuid();     String photolocation = photoID.ToString() + ".jpg";  //file name       encoder.Frames.Add(BitmapFrame.Create((BitmapImage)sender));      using (var filestream = new FileStream(photolocation, FileMode.Create))       encoder.Save(filestream);   }  } 
like image 95
Chris Baxter Avatar answered Sep 24 '22 18:09

Chris Baxter