2

I have a bitmap image of a person and I would like to draw a rectangle over the person's face. I have the coordinates of the rectangle (x, y, width, height). Like this:

enter image description here

If I were using WPF, then I could achieve this using the DrawingVisual and DrawingContext classes. Unfortunately they are not available in UWP. Are there any equivalent API's available or maybe a NuGet package to achieve the same functionality?

kkyr
  • 3,785
  • 3
  • 29
  • 59
  • have you checked the following link https://msdn.microsoft.com/en-us/library/windows/apps/dn894631.aspx – MethodMan Nov 27 '15 at 22:27
  • Yes did I miss anything? – kkyr Nov 27 '15 at 22:34
  • from reading the link that was posted I gathered that UWP uses some of the `System.*` namespace like in windows so I am assuming that it should be able to work similar to how it works in Windows System – MethodMan Nov 27 '15 at 22:36
  • The WPF classes I mentioned are from the `System.Windows.Media` namespace which is not available in UWP. – kkyr Nov 27 '15 at 22:42
  • [System.Windows.Media](https://msdn.microsoft.com/en-us/library/system.windows.media.drawingcontext(v=vs.110).aspx) – MethodMan Nov 27 '15 at 22:46
  • This is not available in UWP ... – kkyr Nov 27 '15 at 22:51
  • can you copy that dll and reference in UWP..? I am sure that has to be away around this – MethodMan Nov 27 '15 at 22:52
  • That seems like a dirty way - wouldn't that break the app on mobile devices? – kkyr Nov 27 '15 at 23:05
  • 1
    There is nothing like DrawingVisual in Windows Runtime. Put a Rectangle or a Path with a RectangleGeometry on top of an Image control. – Clemens Nov 27 '15 at 23:08
  • I am not sure on Mobile app or not but I assume that it's the same functionality when doing web application think of it as if you were consuming a 3rd party .dll this is the best way I can explain it.. – MethodMan Nov 27 '15 at 23:13
  • System.Windows.Media is WPF. That is an entirely different framework than Windows Runtime and is not available to UWP apps. No way. – Clemens Nov 27 '15 at 23:16
  • Ok Clemens, I will look through some more NuGet packages and if I don't find anything I'll resort to what u suggested. – kkyr Nov 27 '15 at 23:18
  • Do you want to rewrite image pixels with blue pixels or just place a rectangle over the image in the tree of the elements? – Juan Pablo Garcia Coello Nov 29 '15 at 08:35
  • I wanted a rectangle on top of the image. I have found a solution and posted it. – kkyr Nov 29 '15 at 11:14

2 Answers2

1

A solution I have come up with is encompassing the image in a Grid and placing an ItemsControl on top of it which is bound to a set of rectangles and a Canvas as a panel template:

<Grid>
    <Image Source="{Binding Image}" />
    <ItemsControl ItemsSource="{Binding Rectangles}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Helper:BindingHelper.CanvasLeftBindingPath" Value="Left" />
                <Setter Property="Helper:BindingHelper.CanvasTopBindingPath" Value="Top" />
             </Style>
        </ItemsControl.ItemContainerStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Rectangle Width="{Binding Width}"
                           Height="{Binding Height}"
                           Stroke="{Binding Color}"
                           StrokeThickness="6">
                </Rectangle>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

Since Binding in a style setter is not supported in UWP I had to use a binding helper. More about that can be found here UWP Binding in Style Setter not working

Community
  • 1
  • 1
kkyr
  • 3,785
  • 3
  • 29
  • 59
1

I am using the 'WriteableBitmapEx' Nuget Package solved this problem. More information is http://kaki104.tistory.com/517

Sample code:

private async void BrowseButton_Click(object sender, RoutedEventArgs e)
{
    //FileOpePicker
    var openDlg = new FileOpenPicker();
    openDlg.FileTypeFilter.Add(".jpg");
    openDlg.FileTypeFilter.Add(".jpeg");
    openDlg.FileTypeFilter.Add(".png");
    //Open file selection window
    var result = await openDlg.PickSingleFileAsync();
    if (result == null || !result.IsAvailable) return;
    var file = await StorageFile.GetFileFromPathAsync(result.Path);
    var property = await file.Properties.GetImagePropertiesAsync();
    //Create bitmap from image size
    var writeableBmp = BitmapFactory.New((int)property.Width, (int)property.Height);
    using (writeableBmp.GetBitmapContext())
    {
        //Load bitmap from image file
        using (var fileStream = await file.OpenAsync(FileAccessMode.Read))
        {
            writeableBmp = await BitmapFactory.New(1, 1).FromStream(fileStream, BitmapPixelFormat.Bgra8);
        }
    }

    //find face that DetectAsync Face API
    using (var imageFileStream = await file.OpenStreamForReadAsync())
    {
        var faces = await faceServiceClient.DetectAsync(imageFileStream);
        if (faces == null) return;
        //display rect
        foreach (var face in faces)
        {
            writeableBmp.DrawRectangle(face.FaceRectangle.Left, face.FaceRectangle.Top,
            face.FaceRectangle.Left + face.FaceRectangle.Width,
            face.FaceRectangle.Top + face.FaceRectangle.Height, Colors.Red);
        }
    }
    FacePhoto.Source = writeableBmp;
}
Munchan Park
  • 61
  • 1
  • 3