我有两个,我想合并到一起的位图图像。 我发现我可以做到这一点WriteableBitmap的,但我怎么先转换这些图片writeablebitmaps?
更新:我找不到出路位图转换为可写的位图直接所以我所做的就是写我的位图在独立存储和数据流对象读一遍。 这之后通过Xyroid下面给出的代码可用于合并图像和所述合并的图像转换为位图。
我有两个,我想合并到一起的位图图像。 我发现我可以做到这一点WriteableBitmap的,但我怎么先转换这些图片writeablebitmaps?
更新:我找不到出路位图转换为可写的位图直接所以我所做的就是写我的位图在独立存储和数据流对象读一遍。 这之后通过Xyroid下面给出的代码可用于合并图像和所述合并的图像转换为位图。
在这里,我给你的代码合并两个图像。 WinRT中的WriteableBitmap的不同的是,它的构造函数有高度和宽度作为参数。 我已经使用WriteableBitmapEx某些功能。
XAML
<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>
C#
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;
}
请注意,您必须添加System.Runtime.InteropServices.WindowsRuntime
命名空间。
更新1
假设,如果你有已经有两个BitmapImage
img1
和img2
,然后做这样的
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;
}
我已经做了很多工作,使用Silverlight,我相信商店的应用程序类似于在许多方面。
考虑这个构造函数:
WriteableBitmap(BitmapSource)
- Initializes a new instance of the WriteableBitmap class using the
provided BitmapSource.
接下来的问题是,如何从图像获取“的BitmapSource”? 你可以这样来做:
(BitmapSource)MyImage.Source
虽然这假定源(它是类型“的ImageSource”的)实际上是一个“的BitmapSource”实例。 这就是说,作为Silverlight的5.0的,从ImageSource的Silverlight中得到的唯一的类的BitmapSource,所以我怀疑这将是一个问题。
因此,像这样可能工作:
WriteableBitmap((BitmapSource)MyImage.Source)
最后,这里有一个开源项目,这可能会有所帮助: http://writeablebitmapex.codeplex.com/