UWP 画布像素操作

问题描述

我设法创建了一个画布,用户可以使用 this Microsoft example 在其上绘图。

现在我要计算白色和黑色像素的数量。并且还修改了一些像素的颜色。

我找不到任何关于如何从画布中获取所有像素数据并对其进行操作和更新的示例。

<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,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>
#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);
}

我怎样才能做到这一点?

解决方法

以下代码基于链接示例的Scenario3中的代码:

Image 控件放入与 InkCanvas 中的 Scenario3.xaml 相同的容器中。注意在Image控件前面添加InkCanvas控件。

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

Scenario3.xaml.cpp 文件中,找到 OnLoadAsync 方法。注释或删除原始 return 语句并添加新语句:

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();
        }
    });
}

请注意,更改后的图像显示在 Image 控件中,您无法通过 保存 按钮再次保存图像,该按钮用于将 InkCanvas 的墨水保存在 场景 3。