alurab
alurab

Reputation: 42

How to concat two images programatically using UWP

I can get an image of a grid in my application using:

RenderTargetBitmap rtb_grid = new RenderTargetBitmap();
await rtb_grid.RenderAsync(grid);
var grid_pixel_buffer = await rtb_grid.GetPixelsAsync();
var grid_pixels = grid_pixel_buffer.ToArray();

And I know I can save this to external file (in this case a stream) using:

var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
       BitmapAlphaMode.Premultiplied,
       (uint)rtb_grid.PixelWidth,
       (uint)rtb_grid.PixelHeight,
       displayInformation.RawDpiX,
       displayInformation.RawDpiY,
       grid_pixels);

But in my scenario, now I have two different grids in different places with their corresponding pixels (byte[]). So how can I concat these images (left to right) in just one, to perform the second step saving only a bigger image with the first two inside?

Upvotes: 0

Views: 107

Answers (1)

Faywang - MSFT
Faywang - MSFT

Reputation: 5868

To concat two images programatically, you can try to use Win2D method to achieve. Create a CanvasRenderTarget among with the total size of two images first, then draw these two images onto it with bytes. After that, saving it to your file. For example:

.xaml:

<StackPanel>
    <Grid x:Name="ImageA">
        <Image  Source="Assets/StoreLogo.png"></Image>
    </Grid>
    <Grid x:Name="ImageB">
        <Image  Source="Assets/3.jpg"></Image>
    </Grid>
</StackPanel>

.cs:

public async void SaveImage() 
{
    RenderTargetBitmap rtb_grid = new RenderTargetBitmap();
    await rtb_grid.RenderAsync(ImageA);
    var grid_pixel_buffer = await rtb_grid.GetPixelsAsync();
    byte[] grid_pixels = grid_pixel_buffer.ToArray();

    RenderTargetBitmap rtb_grid2 = new RenderTargetBitmap();
    await rtb_grid2.RenderAsync(ImageB);
    var grid_pixel_buffer2 = await rtb_grid2.GetPixelsAsync();
    byte[] grid_pixels2 = grid_pixel_buffer2.ToArray();

    StorageFile destinationFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("MyImge.png", CreationCollisionOption.ReplaceExisting);
    CanvasDevice device = CanvasDevice.GetSharedDevice();

    CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (int)(rtb_grid.PixelWidth + rtb_grid2.PixelWidth), Math.Max(rtb_grid.PixelHeight, rtb_grid2.PixelHeight), 96);
           
    using (var ds = renderTarget.CreateDrawingSession())
    {
        ds.Clear(Colors.White);
        var image = CanvasBitmap.CreateFromBytes(device, grid_pixels,rtb_grid.PixelWidth,rtb_grid.PixelHeight, DirectXPixelFormat.B8G8R8A8UIntNormalized);
        ds.DrawImage(image,0,0);
                
        var image2 = CanvasBitmap.CreateFromBytes(device, grid_pixels2, rtb_grid2.PixelWidth, rtb_grid2.PixelHeight, DirectXPixelFormat.B8G8R8A8UIntNormalized);
        ds.DrawImage(image2, (float)rtb_grid.PixelWidth, 0);
    }      

    using (var fileStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f);
    }
}

Upvotes: 1

Related Questions