我有以下XAML:
<Image Visibility="Visible"
Source="{Binding ElementName=inkCanvas,
Converter={StaticResource InkCanvasToImageSource},
UpdateSourceTrigger=PropertyChanged}">
</Image>
<InkCanvas x:Name="inkCanvas" />
我要做的是将InkCanvas Stroke Collection转换为BitmapImage。我正在使用MVVM,并希望在命令上执行此操作。我遇到的问题是上面的代码不会触发转换器触发。我正在使用UWP,因此我只能将其中一个控件作为命令参数传递。
我需要一种方法从一种方法转换为另一种方法,但我想在ViewModel中进行。
答案 0 :(得分:1)
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "iostream"
using namespace cv;
double contrast_measure( const Mat&img )
{
Mat dx, dy;
Sobel( img, dx, CV_32F, 1, 0, 3 );
Sobel( img, dy, CV_32F, 0, 1, 3 );
magnitude( dx, dy, dx );
return sum(dx)[0];
}
int main( int argc, char** argv )
{
char* filename = argc >= 2 ? argv[1] : (char*)"lena.jpg";
Mat src = imread( filename );
if(src.data)
{
std::cout << "original image : " << contrast_measure( src ) / 1e3 << std::endl;
for( int i =3; i < 80; i+=2 )
{
Mat blurred;
GaussianBlur( src, blurred, Size(i,i), 0);
imshow( "blurred image", blurred );
waitKey(200);
std::cout << "blurred image : " << contrast_measure( blurred ) / 1e3 << std::endl;
}
}
return 0;
}
控件与InkPresenter
对象的实例相关联(通过InkPresenter
属性公开)。 InkCanvas
提供用于管理InkPresenter
控件的墨迹数据的输入,处理和呈现的属性,方法和事件。因此,绑定到InkCanvas
不会触发转换器触发,因为墨迹输入完全由InkCanvas
管理。并且InkPresenter
属性不是依赖属性,我们无法绑定到此属性。因此,我们无法强制将InkCanvas.InkPresenter
更新与Image
绑定。我们必须在代码隐藏中执行此操作,这可能会破坏MVVM设计。
要更新InkCanvas
,我们可以使用Image
和StrokesCollected
事件来检测墨迹输入,并在这些事件中将所有StrokesErased
个对象保存到InkStroke
。例如:
在XAML中
BitmapImage
在代码隐藏中:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Image x:Name="MyImage" />
<Border Grid.Row="1" BorderBrush="Red" BorderThickness="2">
<InkCanvas x:Name="inkCanvas" />
</Border>
</Grid>
我只是将图片设置为public MainPage()
{
this.InitializeComponent();
...
inkCanvas.InkPresenter.StrokesCollected += InkPresenter_StrokesCollected;
inkCanvas.InkPresenter.StrokesErased += InkPresenter_StrokesErased;
}
private async void InkPresenter_StrokesErased(InkPresenter sender, InkStrokesErasedEventArgs args)
{
var image = await SaveAsync();
MyImage.Source = image;
}
private async void InkPresenter_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
{
var image = await SaveAsync();
MyImage.Source = image;
}
private async Task<BitmapImage> SaveAsync()
{
var bitmap = new BitmapImage();
if (inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Count > 0)
{
try
{
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await inkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream);
stream.Seek(0);
bitmap.SetSource(stream);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
}
return bitmap;
}
,您也可以将其设置为ViewModel并在MyImage
中使用Binding
。