C# 我可以将图像/位图转换为可写位图吗?
我有两个位图图像,我想合并在一起。我发现我可以用writeablebitmap实现这一点,但如何首先将这些图像转换为writeablebitmapsC# 我可以将图像/位图转换为可写位图吗?,c#,windows-runtime,windows-store-apps,C#,Windows Runtime,Windows Store Apps,我有两个位图图像,我想合并在一起。我发现我可以用writeablebitmap实现这一点,但如何首先将这些图像转换为writeablebitmaps 更新:我找不到一种直接将位图转换为可写位图的方法,所以我所做的是在独立存储中写入位图,然后在流对象中再次读取。之后,可以使用下面Xyroid提供的代码合并图像并将合并的图像转换为位图。我对Silverlight做了很多工作,我相信商店应用程序在许多方面与Silverlight类似 考虑这个构造函数: WriteableBitmap(BitmapSo
更新:我找不到一种直接将位图转换为可写位图的方法,所以我所做的是在独立存储中写入位图,然后在流对象中再次读取。之后,可以使用下面Xyroid提供的代码合并图像并将合并的图像转换为位图。我对Silverlight做了很多工作,我相信商店应用程序在许多方面与Silverlight类似 考虑这个构造函数:
WriteableBitmap(BitmapSource)
- Initializes a new instance of the WriteableBitmap class using the
provided BitmapSource.
下一个问题是,如何从图像中获取“BitmapSource”?您可以这样做:
(BitmapSource)MyImage.Source
尽管这假设源(类型为“ImageSource”)实际上是“BitmapSource”实例。也就是说,从Silverlight 5.0开始,Silverlight中唯一从ImageSource派生的类是BitmapSource,因此我怀疑这是否会成为一个问题
因此,类似这样的方法可能会奏效:
WriteableBitmap((BitmapSource)MyImage.Source)
最后,这里有一个开源项目可能会有所帮助:这里我给您提供了合并两个图像的代码。WinRT的WriteableBitmap不同,它的构造函数以高度和宽度作为参数。我已经使用了一些函数 XAML
你试过什么吗?我试过writeablebitmap(img),但它说writeablebitmap没有只接受一个参数的构造函数。我只能给出int-height和int-width作为参数。我已经在互联网上搜索了一个小时,我所能找到的是,只有当你从某个位置打开它时,你才能制作一个可写的位图。但是,我的图像是由用户或应用程序(取决于用户)放置在画布控件上的……我尝试了这一点,但我得到了以下两个错误:1Windows.UI.Xaml.Media.Imaging.WriteableBitmap”是一个“类型”,但其使用方式类似于“变量”2“Windows.UI.Xaml.Media.Imaging.BitmapSource”是一个“类型”,但像“变量”一样使用。您所说的构造函数不起作用。我不知道为什么。。我已经实现了你给我的链接库。好的,对不起,它认为微软会继续走不一致的道路。我知道它在Silverlight(也是XAML)中工作:/非常感谢你的帮助。我真的很感激:)非常感谢你的代码。它运行得非常好。我将能够实现我想要的一些编辑。再次感谢:)不客气,特莱姆。请投票给我的答案,我会很高兴。如果你不说的话,我会这么做的,但我还不能,因为我是一个新用户。在这个例子中,你将从资产文件夹中获得文件1和文件2中的两个图像。而我拥有的图像已按应用程序存储在两个BitmapImage对象中。知道如何将它们转换为可写位图、像素流或字节数组吗?我正在从
StorageFile
创建BitmapImage
,因此您可以跳过该部分。你面临什么问题?
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Canvas x:Name="BaseCanvas" Width="683" Height="768">
<Image Source="Assets/img1.png" />
<Image Source="Assets/img2.png" Canvas.Top="308" />
</Canvas>
<Image x:Name="imgTarget" Grid.Column="1" Stretch="None"/>
</Grid>
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
StorageFile destiFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("Merged.png", CreationCollisionOption.ReplaceExisting);
WriteableBitmap wb;
wb = await Render();
using (IRandomAccessStream stream = await destiFile.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(
BitmapEncoder.PngEncoderId, stream);
Stream pixelStream = wb.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)wb.PixelWidth, (uint)wb.PixelHeight, 96.0, 96.0, pixels);
await encoder.FlushAsync();
}
var bitmp = new BitmapImage();
using (var strm = await destiFile.OpenReadAsync())
{
bitmp.SetSource(strm);
imgTarget.Source = bitmp;
}
}
private async Task<WriteableBitmap> Render()
{
var Assets = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
StorageFile file1 = await Assets.GetFileAsync("img1.png");
StorageFile file2 = await Assets.GetFileAsync("img2.png");
BitmapImage i1 = new BitmapImage();
BitmapImage i2 = new BitmapImage();
using (IRandomAccessStream strm = await file1.OpenReadAsync())
{
i1.SetSource(strm);
}
using (IRandomAccessStream strm = await file2.OpenReadAsync())
{
i2.SetSource(strm);
}
WriteableBitmap img1 = new WriteableBitmap(i1.PixelWidth, i1.PixelHeight);
WriteableBitmap img2 = new WriteableBitmap(i2.PixelWidth, i2.PixelHeight);
using (IRandomAccessStream strm = await file1.OpenReadAsync())
{
img1.SetSource(strm);
}
using (IRandomAccessStream strm = await file2.OpenReadAsync())
{
img2.SetSource(strm);
}
WriteableBitmap destination = new WriteableBitmap((int)(img1.PixelWidth > img2.PixelWidth ? img1.PixelWidth : img2.PixelWidth), (int)(img1.PixelHeight + img1.PixelHeight));
destination.Clear(Colors.White);
destination.Blit(new Rect(0, 0, (int)img1.PixelWidth, (int)img1.PixelHeight),img1,new Rect(0, 0, (int)img1.PixelWidth, (int)img1.PixelHeight));
destination.Blit(new Rect(0, (int)img1.PixelHeight, (int)img2.PixelWidth, (int)img2.PixelHeight), img2, new Rect(0, 0, (int)img2.PixelWidth, (int)img2.PixelHeight));
return destination;
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
StorageFile destiFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("Merged.png", CreationCollisionOption.ReplaceExisting);
WriteableBitmap wb;
wb = await Render();
using (IRandomAccessStream stream = await destiFile.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(
BitmapEncoder.PngEncoderId, stream);
Stream pixelStream = wb.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)wb.PixelWidth, (uint)wb.PixelHeight, 96.0, 96.0, pixels);
await encoder.FlushAsync();
}
var bitmp = new BitmapImage();
using (var strm = await destiFile.OpenReadAsync())
{
bitmp.SetSource(strm);
imgTarget.Source = bitmp;
}
}
private async Task<WriteableBitmap> Render()
{
WriteableBitmap destination = new WriteableBitmap((int)(img1.PixelWidth > img2.PixelWidth ? img1.PixelWidth : img2.PixelWidth), (int)(img1.PixelHeight + img1.PixelHeight));
destination.Clear(Colors.White);
destination.Blit(new Rect(0, 0, (int)img1.PixelWidth, (int)img1.PixelHeight),img1,new Rect(0, 0, (int)img1.PixelWidth, (int)img1.PixelHeight));
destination.Blit(new Rect(0, (int)img1.PixelHeight, (int)img2.PixelWidth, (int)img2.PixelHeight), img2, new Rect(0, 0, (int)img2.PixelWidth, (int)img2.PixelHeight));
return destination;
}