如何在C#中有效地将BitmapSource转换为byte [],反之亦然?
我有一个问题,我的WPF应用程序.我正在尝试使用viewmodel中的image属性在我的gridview中对图像字段进行数据绑定.
<DataGridTemplateColumn Header="Image" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=Image, IsAsync=True}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Run Code Online (Sandbox Code Playgroud)
如果我不使用IsAsync,这没问题.但是,我想做异步,因为它需要加载大量图像,并且需要从Web服务加载它们.
Image属性的代码是this,它只调用一个调用web服务的处理程序dll.
public BitmapSource Image
{
get { return image ?? (image = ImageHandler.GetDefaultImages(new[] {ItemNumber},160,160)[0].BitmapSource()); }
}
Run Code Online (Sandbox Code Playgroud)
但是,只要我添加了IsAsync = true,我就会在表单加载后得到以下异常:
The calling thread cannot access this object because a different thread owns it.
我是WPF的新手,我有点假设,当async设置为true时,它处理了线程本身.在数据绑定中是否需要以某种方式调用?如果是这样,我该怎么做呢?
对流不了解很多.为什么第一个版本使用文件但第二个版本没有?在"返回目标"上设一个断点 看起来两者都创建了完全相同的东西,但dest始终是使用第二个版本的空白图像.
public static BitmapSource ConvertByteArrayToBitmapSource(Byte[] imageBytes, ImageFormat formatOfImage)
{
BitmapSource dest = null;
if (formatOfImage == ImageFormat.Png)
{
var streamOut = new FileStream("tmp.png", FileMode.Create);
streamOut.Write(imageBytes, 0, imageBytes.Length);
streamOut.Close();
Uri myUri = new Uri("tmp.png", UriKind.RelativeOrAbsolute);
var bdecoder2 = new PngBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
dest = bdecoder2.Frames[0];
}
return dest;
}
public static BitmapSource ConvertByteArrayToBitmapSource_NoWork(Byte[] imageBytes, ImageFormat formatOfImage)
{
BitmapSource dest = null;
using (var stream = new MemoryStream(imageBytes))
{
var bdecoder = new PngBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
stream.Flush();
dest = bdecoder.Frames[0];
stream.Close(); …Run Code Online (Sandbox Code Playgroud) 关键是,我需要转换为System.Drawing.Bitmap(.Net Framework 2.0)以获取WPF Grid的单帧及其内容.
我读到了VisualBrush,DrawingBrush但我无法想象它应该如何运作.
我可以将任何WPF BitmapSource转换成我的System.Drawing.Bitmap成功.但是如何BitmapSource从我的网格接收?
谢谢
如何将BitmapSource转换为MemoryStream.虽然我尝试了一些代码:
private Stream StreamFromBitmapSource(BitmapSource writeBmp)
{
Stream bmp;
using (bmp = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(writeBmp));
enc.Save(bmp);
}
return bmp;
}
Run Code Online (Sandbox Code Playgroud)
它没有给出任何错误但是在调试点之后它显示了一些下面列出的异常.
容量:'printStream.Capacity'引发类型'System.ObjectDisposedException'的异常长度:'printStream.Length'抛出类型'System.ObjectDisposedException'的异常位置:'printStream.Position'抛出类型'System.ObjectDisposedException的异常"
好的,我试过这个:
TransformedBitmap tbm = new TransformedBitmap(myBitmapSource, new RotateTransform(angle));
return tbm;
Run Code Online (Sandbox Code Playgroud)
但这不适用于 90 度倍数以外的角度。
新我尝试使用 RenderTargetBitmap:
var image = new Canvas();
image.Width = myBitmapSource.PixelWidth;
image.Height = myBitmapSource.PixelHeight;
image.Background = new ImageBrush(myBitmapSource);
image.RenderTransform = new RotateTransform(angle);
RenderTargetBitmap rtb = new RenderTargetBitmap(myBitmapSource.PixelWidth, myBitmapSource.PixelHeight, myBitmapSource.DpiX, myBitmapSource.DpiY, myBitmapSource.Format);
rtb.Render(image);
return rtb;
Run Code Online (Sandbox Code Playgroud)
但这给了我:
"The calling thread must be STA, because many UI components require this."
Run Code Online (Sandbox Code Playgroud)
这在没有 GUI 的服务中运行。
有人可以给我一个关于如何以任何角度旋转 WPF(没有 GUI)中的 BitmapSource 的工作代码示例吗?
更新:
投票功能请求:http : //visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/10870098-allow-rotation-of-bitmapsource-by-any-angle
bitmapsource ×6
wpf ×6
c# ×5
asynchronous ×1
data-binding ×1
datagridview ×1
drawing ×1
memorystream ×1
pixels ×1
stream ×1
visualbrush ×1