2017-04-07 26 views
2

我有一個使用UWP InkCanvas的UWP應用程序,帶有加載和保存墨水按鈕。我在一臺筆記本電腦上繪製了應用程序的繪圖,將繪圖保存爲gif(+嵌入式isf),並將gif文件發送到另一臺帶有較小屏幕的筆記本電腦進行試用。當切換PC InkCanvas筆畫時沒有以適當的邊界呈現PC

當使用相同的應用程序打開墨水時,在其他筆記本電腦上打開時,繪圖被裁剪在邊界處,就好像它不適合屏幕一樣,這可能是由於筆記本電腦的屏幕較小。

我試圖通過將其封裝在滾動查看器中來將InkCanvas整體調整大小,但繪圖遵循InkC​​anvas縮放,因此繪製仍然在邊界處被裁剪。與InkCanvas上的渲染轉換相同。加載墨水時,我也嘗試了StrokeContainer的複製粘貼方法。它不起作用,而且我覺得它體積龐大,因爲需要遍歷所有筆畫來選擇它們,然後複製粘貼。

我正在尋找一種方法來自動調整InkCanvas(首選)或Strokes的大小,使繪圖完全顯示在InkCanvas上,而不管筆記本電腦屏幕的大小如何。我期待這種情況在默認情況下發生,但有些情況下不會。

雖然我使用的代碼是很簡單的,我將它作爲一個開始:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <Grid Background="White" Grid.Row="1"> 
     <InkCanvas x:Name="inkCanvas"/> 
    </Grid> 
    <StackPanel> 
      <Button Content="Load" Click="LoadButton_Click"/> 
      <Button Content="Save" Click="SaveButton_Click"/> 
    </StackPanel> 
</Grid> 


    private async void LoadButton_Click(object sender, RoutedEventArgs e) 
    { 
     FileOpenPicker openPicker = new FileOpenPicker(); 
     openPicker.FileTypeFilter.Clear(); 
     openPicker.FileTypeFilter.Add(".isf"); 
     openPicker.FileTypeFilter.Add(".gif"); 

     openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; 

     StorageFile file = await openPicker.PickSingleFileAsync(); 

     if (file != null) 
     { 
      IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read); 

      using (var inputStream = stream.GetInputStreamAt(0)) 
      { 
       await inkCanvas.InkPresenter.StrokeContainer.LoadAsync(inputStream); 
      } 
      stream.Dispose(); 

    } 
    } 
+0

你還可以包含'SaveButton_Click'事件處理程序嗎? – Laith

回答

3

StrokeContainer.SaveAsync()方法將創建一個GIF。我不確定它是如何保留墨跡筆跡數據的,但它似乎是重點。由於您的InkCanvas正在根據其母公司Grid進行拉伸,因此其最終邊界將以不同的屏幕顯示,即使在調整大小的UWP窗口中也是如此。

因此,當您重新加載筆劃數據時,它會將這些點準確放置在生成的位置。它不會爲你改變任何東西。這是原始數據。

如果您希望數據顯示在不同位置,則可以對點應用轉換。下面是如何通過50%的收縮所有數據的快速採樣:

var container = inkCanvas.InkPresenter.StrokeContainer; 
var strokes = container.GetStrokes(); 
var bounds = container.BoundingRect; 
var center = new Vector2((float)bounds.Left, (float)bounds.Top); 
var transform = Matrix3x2.CreateScale(.5f, .5f, center); 

foreach (var stroke in strokes) 
{ 
    stroke.PointTransform *= transform; 
} 

你可以把該代碼段await container.LoadAsync(inputStream)後。

您需要決定如何處理輸出。這將取決於您想要的用戶體驗。如果您想縮放輸出,請使用上面的代碼片段。如果你想移動它,然後使用Matrix3x2.CreateTranslation(...)

+0

Laith,我嘗試了一些類似的工具,但LoaadAsync已經加載了所有筆劃和顯示。實施變換需要我隱藏畫布以改善用戶體驗,否則用戶將在重新顯示期間看到閃光燈。人們還應該用相同的因子來縮放筆畫的大小。這使我想到了這樣的問題:如何讀取原始數據而不顯示它們(因此覆蓋LoadAsync或創建一個新的Load方法),轉換數據並顯示。它會更乾淨。但我不知道如何加載我自己的數據並能夠讀取筆畫對象。乾杯 – Octopus

+0

'inkCanvas.Opacity = 0' ...加載數據...'inkCanvas.Opacity = 1' ...是否有效? – Laith

+0

我沒有嘗試不透明,但我認爲它會起作用。我通過關閉可見性來實現它的工作。 – Octopus