UWP Canvas Pixel Manipulation

newbie1234 1 Reputation point
2021-03-03T00:08:45.327+00:00

I managed to create a canvas and a user can draw on it using this Microsoft example.

Now I want to count the number of white and black pixels. And also modify colors of some of the pixels.

I could not find any example on how to get all the pixel data from canvas and manipulate and update it.

How can I achieve this???

#include "pch.h"
#include "Scenario1.xaml.h"
#include "SampleConfiguration.h"

using namespace SDKTemplate;

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;

Scenario1::Scenario1()
{
    InitializeComponent();

    // Initialize the InkCanvas
    inkCanvas->InkPresenter->InputDeviceTypes =
        CoreInputDeviceTypes::Mouse |
        CoreInputDeviceTypes::Pen;


}


void Scenario1::OnSizeChanged(Object^ sender, SizeChangedEventArgs^ e)
{
    HelperFunctions::UpdateCanvasSize(RootGrid, outputGrid, inkCanvas);
}



<Page
    x:Class="SDKTemplate.Scenario1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    SizeChanged="OnSizeChanged"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid x:Name="RootGrid" Margin="12,10,12,12">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <StackPanel Margin="0,0,0,10">
                <TextBlock Text="Description:" Style="{StaticResource SampleHeaderTextStyle}"/>
                <TextBlock Style="{StaticResource ScenarioDescriptionTextStyle}" TextWrapping="Wrap">
                This scenario adds an InkCanvas and InkToolbar to the page.<LineBreak/>
                    - Use either pen or mouse to ink.<LineBreak/>
                    - A chevron glyph on the active tool button indicates that additional settings are available in a flyout. Select the active tool once more to display the flyout.
                </TextBlock>
            </StackPanel>
            <ScrollViewer Grid.Row="1" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
                <Grid HorizontalAlignment="Left" VerticalAlignment="Top">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <InkToolbar Grid.Row="0" TargetInkCanvas="{x:Bind inkCanvas}"/>
                    <ScrollViewer Grid.Row="1" x:Name="scrollViewer" ZoomMode="Enabled" MinZoomFactor="1" VerticalScrollMode="Enabled" VerticalScrollBarVisibility="Auto" HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Auto">
                        <Grid x:Name="outputGrid" Background="{ThemeResource SystemControlBackgroundChromeWhiteBrush}" Height="Auto">
                            <!-- Inking area -->
                            <InkCanvas x:Name="inkCanvas" Height="Auto"/>
                        </Grid>
                    </ScrollViewer>
                </Grid>
            </ScrollViewer>
        </Grid>
    </Grid>
</Page>
Developer technologies | Universal Windows Platform (UWP)
Developer technologies | C++
Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. Yan Gu - MSFT 2,676 Reputation points
    2021-03-04T01:59:44.627+00:00

    Hello,

    Welcome to Microsoft Q&A.

    The following code is based on the code in Scenario3 of the linked sample:

    Put an Image control into the same container as InkCanvas in Scenario3.xaml. Note to add the Image control in the front of InkCanvas control.

    <Grid x:Name="outputGrid" Background="{ThemeResource SystemControlBackgroundChromeWhiteBrush}">  
        <!-- Inking area -->  
        <Image x:Name="inkImage" Stretch="None"/>  
        <InkCanvas x:Name="inkCanvas">  
        </InkCanvas>  
    </Grid>  
    

    In Scenario3.xaml.cpp file, find the OnLoadAsync method. Comment or delete the original return statement and add a new one:

    void Scenario3::OnLoadAsync(Object^ sender, RoutedEventArgs^ e)  
    {  
        auto openPicker = ref new FileOpenPicker();  
        openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;  
        openPicker->FileTypeFilter->Append(".gif");  
        openPicker->FileTypeFilter->Append(".isf");  
      
        create_task(openPicker->PickSingleFileAsync()).then([this](StorageFile^ file)  
        {  
            if (file != nullptr)  
            {  
                return create_task(file->OpenAsync(Windows::Storage::FileAccessMode::Read)).then([this](IRandomAccessStream^ fileStream)  
                {  
                    // Set the image source to the selected bitmap  
                    auto bitmapImage = ref new BitmapImage();  
                    bitmapImage->SetSource(fileStream);  
                    inkImage->Source = bitmapImage;  
                });  
      
            }  
            else  
            {  
                return task_from_result();  
            }  
        });  
    }  
    

    Note that changed images are shown in Image control, and you couldn’t save images again by the Save button which is used to save inks of InkCanvas in Scenario3.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.