Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
193 views
in Technique[技术] by (71.8m points)

c# - Save BitmapImage to File

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.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
  } 
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...