locked
Merging Images with Composite Transform

    Question

  • Hi,

    Before getting to the question let me give a brief intro to the app so that anyone can better understand the question. 

    In my App i have 3 screens. In the first screen user captures an image from the camera. On the second screen the captured photo is set as background, on top of that i have an image which can be moved, scaled or rotated. On the third screen i have to merge those two images and save it as a PNG image so that the user can share the image. This is where i'm struck in. 

    I'm having problem merging the two images. I'm using WriteableBitmap.Blit already to accomplish this. But since the second image is rotated and scaled i can't merge second image on top of first image with that exact rotation and scaling applied.

    Here is the code 

    Screen 2

                
    <Grid Grid.Row="1" x:Name="gridLayers">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="240"/>
                </Grid.ColumnDefinitions>
    
                    <Image x:Name="backgroundImage"></Image>
    
                    <Image x:Name="layer1Image" ImageOpened="layerImage_Opened">
                        <Image.RenderTransform>
                            <!--<RotateTransform x:Name="layer1Rotation"/>-->
                            <CompositeTransform x:Name="layer1ImageTransform"></CompositeTransform>
                        </Image.RenderTransform>
                    </Image>
    
    </Grid>

    And the code behind

    private void step2OK_Click(object sender, RoutedEventArgs e)
            {
                RotationAngle_Step3Image = this.layer1ImageTransform.Rotation;
                TranslateX_Step3Image = layer1ImageTransform.TranslateX;
                TranslateY_Step3Image = layer1ImageTransform.TranslateY;
                ScaleX_Step3Image = layer1ImageTransform.ScaleX;
                ScaleY_Step3Image = layer1ImageTransform.ScaleY;
    
            }


    So now i have all the rotation, Translation & Scale value. Now i apply that to the image merging using blit.

    //Background image
    WriteableBitmap wbBackground = new WriteableBitmap(biBackGroundImage.PixelWidth, biBackGroundImage.PixelHeight);
                        wbBackground.SetSource(stream);
                        merge.Blit(new Rect(0, 0, biBackGroundImage.PixelWidth, biBackGroundImage.PixelHeight), wbBackground, new Rect(0, 0, biBackGroundImage.PixelWidth, biBackGroundImage.PixelHeight));
    
    
    //layer1 image
    BitmapImage biFile = layer1Image.Source as BitmapImage;
                            WriteableBitmap wbFile = await GetWritableBitMap(biFile, layer1ImageTransform, Windows.UI.Colors.Transparent);
    
    //merge
    merge.Blit(new Rect(0, 0, biBackGroundImage.PixelWidth, biBackGroundImage.PixelHeight), wbFile, new Rect(0, 0, biFile.PixelWidth, biFile.PixelHeight));


     private async Task<WriteableBitmap> GetWritableBitMap(BitmapImage biFile, CompositeTransform cTransform, Color color)
            {
                try
                {
                    StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(AppCore.GetFileReadPath(biFile.UriSource.AbsolutePath)));
    
                    var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
                    WriteableBitmap wbFile = new WriteableBitmap(1, 1);
                    wbFile = await WriteableBitmapExtensions.FromStream(wbFile, fileStream);
                    
                    WriteableBitmap destWB = wbFile.Clone();
                    destWB.Clear(color);
    
                    Rect sourceRect = new Rect(0, 0, wbFile.PixelWidth, wbFile.PixelHeight);
                    Point pt = new Point(0, 0);
    
                    pt.X = cTransform.TranslateX;
                    pt.Y = cTransform.TranslateY;
    
                    Rect destRect = new Rect(pt, new Size((int)(wbFile.PixelWidth * cTransform.ScaleX), (int)(wbFile.PixelHeight * cTransform.ScaleY)));
    
                    destWB.Blit(destRect, wbFile, sourceRect);
                    destWB = WriteableBitmapExtensions.RotateFree(destWB, cTransform.Rotation, false);
                    //destWB = WriteableBitmapExtensions.Resize(destWB, (int)(destWB.PixelWidth * ScaleX_Step3Image), (int)(destWB.PixelHeight * ScaleY_Step3Image), WriteableBitmapExtensions.Interpolation.Bilinear);
                    return destWB;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }

    The resulting merge image does not produce correct result. Any one tell me where i'm going wrong? Or there is another approach for doing this?

    PS: I can't use RenderTargetBitmap since i need to target App for Windows 8 too.


    • Edited by Sankar_Krish Friday, April 11, 2014 10:30 AM Refining Question
    Friday, April 11, 2014 6:38 AM

Answers