保存BitmapImage到文件
我正在从一个程序下载图像从一个URL到一个bitmapimage并显示它。接下来,我尝试使用jpegbitmapencoder将bitmapimage保存到硬盘上。该文件已成功创建,但实际的jpeg图像为空或1个黑色像素。保存BitmapImage到文件
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
FileStream filestream = new FileStream(photolocation, FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(objImage));
encoder.Save(filestream);
return photoID;
}
这是保存并显示照片的功能。照片显示正确,但保存时会再次显示空白jpeg或1个黑色像素。
当您从Uri创建BitmapImage时,需要时间来下载图像。
如果您检查以下属性,该值将可能是TRUE
objImage.IsDownloading
因此,你多少附加一个监听器DownloadCompleted事件处理程序,将所有处理该事件处理程序。
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);
}
你可能也想添加一个事件处理程序的DownloadFailed,以便适当地处理任何错误情况。
编辑基于Ben的评论
加全样本类:
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);
}
}
我测试了你的代码,同样的问题仍然存在。保存的jpeg为空或具有1个黑色像素。 – 2010-11-12 04:07:30
@Ben - 代码运行...更新的答案将用于测试我的答案的完整示例代码;那对你有用吗?应下载9KB Google徽标并将其保存到磁盘。 – 2010-11-12 04:11:20
感谢您的代码完美工作,并且在我的代码中工作。你指出的问题是该照片没有完全从Uri下载。再次,谢谢。 – 2010-11-12 04:37:41
扩大克里斯·巴克斯特的解决方案,这种转换器使用本地版本,如果它存在,否则它下载并保存文件。
using System;
using System.Globalization;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace MyNamespace
{
public sealed class UriToCachedImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var url = value as string;
if (url == null)
return null;
var webUri = new Uri(url, UriKind.Absolute);
var filename = Path.GetFileName(webUri.AbsolutePath);
var localFilePath = Path.Combine("C:\\MyImagesFolder\\", filename);
if (File.Exists(localFilePath))
{
return BitmapFrame.Create(new Uri(localFilePath, UriKind.Absolute));
}
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = webUri;
image.EndInit();
SaveImage(image, localFilePath);
return image;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public void SaveImage(BitmapImage image, string localFilePath)
{
image.DownloadCompleted += (sender, args) =>
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapImage) sender));
using (var filestream = new FileStream(localFilePath, FileMode.Create))
{
encoder.Save(filestream);
}
};
}
}
}
并确保您可以在XAML
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:u="clr-namespace:MyNamespace"
d:DesignHeight="500"
d:DesignWidth="420">
<UserControl.Resources>
<ResourceDictionary>
<u:UriToCachedImageConverter x:Key="UrlToCachedImageConverter" />
</ResourceDictionary>
</UserControl.Resources>
</UserControl>
中访问转换器和使用该转换器的图像
<Image Source="{Binding URL, Mode=OneWay, Converter={StaticResource UrlToCachedImageConverter}, IsAsync=true}"/>
只需使用encoder.Frames.Add(BitmapFrame.Create(新的WriteableBitmap(objImage))); – Andreas 2016-06-09 13:16:55