3

ハイライトストロークをpngとして保存しようと必死です。これを機能させるために、UWPにwin2dを使用しています。不透明度 100% のストロークではうまく機能しますが、 を設定するDrawAsHighlighter = true;と、保存された png は空になり、完全に透明になります。

これが私のコードです:

    private void SetHighLight()
    {
        InkDrawingAttributes attributes = new InkDrawingAttributes();
        attributes.DrawAsHighlighter = true;
        attributes.PenTip = PenTipShape.Rectangle;
        attributes.Size = new Size(4, 10);
        attributes.Color = currentColor;
        SetAttribute(attributes);
    }

    private void GetCanvasRender(out CanvasRenderTarget renderTarget)
    {
        CanvasDevice device = CanvasDevice.GetSharedDevice();
        renderTarget = new CanvasRenderTarget(device, (int)ink.ActualWidth, (int)ink.ActualHeight, 96);
        using (var ds = renderTarget.CreateDrawingSession())
        {
            ds.Clear(Colors.Transparent); //I already tried to delete this but it doesn't change anything
            ds.DrawInk(ink.InkPresenter.StrokeContainer.GetStrokes());
        }
    }

    private async void SavePicture()
    {
        CanvasRenderTarget renderTarget;
        Image img = new Image();

        GetCanvasRender(out renderTarget);
        StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        StorageFile noteFile = await storageFolder.CreateFileAsync(i.ToString() + ".png", CreationCollisionOption.ReplaceExisting);
        using (var fileStream = await noteFile.OpenAsync(FileAccessMode.ReadWrite))
            await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f);
        img.Source = new BitmapImage(new Uri(storageFolder.Path + "/" + i++ + ".png"));
        img.VerticalAlignment = VerticalAlignment.Stretch;
        ContainerCanvas.Children.Add(img);
        Canvas.SetTop(img, ScrollViewerContainer.VerticalOffset);
        Canvas.SetZIndex(img, 5);
    }

ハイライトがビジュアル ツリーに存在しないことが原因である可能性があると読みましたが、それについてはよくわかりません。

ところで、color( attributes.Color = Color.FromArgb(128, 255, 0, 0)) の不透明度を変更しようとすると、inkcanvas がアルファを適用しません。何か不足していますか?

4

3 に答える 3

2

DrawAsHighlighter インクを .png のようなビットマップ形式に保存することはできません。これは、基本的に意味のある操作ではありません。

通常の蛍光ペン以外のインクは、標準のアルファ ブレンディングを使用して描画されるため、これらのインク形状だけをビットマップ形式に書き込むことは合理的です。後でそのビットマップを他の背景画像にブレンドして、インクがその背景に直接描画された場合と同じ結果を得ることができます。

ただし、ハイライター インクの場合、「背景の上にブレンド」はより複雑な操作であり、標準のソースオーバー ブレンディングだけではありません。したがって、このインクだけを含むビットマップ イメージなどというものはありません。適切なブレンドを実行するには、背景も提供する必要があります。

ここには 3 つのオプションがあります。

  1. 蛍光インク モードを使用しないでください。
  2. インクをビットマップ イメージとして保存する代わりに、元のインク ストローク データを保存し、インク API を使用して後でこれらのストロークを最終的な位置に直接ブレンドします。
  3. 背景とインク ストロークを同じビットマップに含めます。
于 2016-04-08T20:43:44.700 に答える
0

私はついにそれを機能させる方法を見つけました。呼び出す前に新しいレイヤーを追加しDrawInkて不透明にし、attributes.DrawAsHighlighter = true;. 代わりに、蛍光ペンを使用しているように見える、蛍光ペン用に特別に不透明度 0.5 の 1 つの inkCanvas を作成しました。

コードは次のとおりです。

private void SetHighLight()
{
    InkDrawingAttributes attributes = new InkDrawingAttributes();
    attributes.PenTip = PenTipShape.Rectangle;
    attributes.Size = new Size(4, 10);
    attributes.Color = currentColor;
    SetAttribute(attributes);
}

private void GetCanvasRender(out CanvasRenderTarget renderTarget, float opacity)
{
    CanvasDevice device = CanvasDevice.GetSharedDevice();
    renderTarget = new CanvasRenderTarget(device, (int)ink.ActualWidth, (int)ink.ActualHeight, 96);
    using (var ds = renderTarget.CreateDrawingSession())
    {
        ds.Clear(Colors.Transparent);
        using (ds.CreateLayer(opacity))
        {
            ds.DrawInk(ink.InkPresenter.StrokeContainer.GetStrokes());
        }
    }
}

private async void SavePicture(float opacity)
{
    CanvasRenderTarget renderTarget;
    Image img = new Image();

    GetCanvasRender(out renderTarget, opacity);
    StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
    StorageFile noteFile = await storageFolder.CreateFileAsync(i.ToString() + ".png", CreationCollisionOption.ReplaceExisting);
    using (var fileStream = await noteFile.OpenAsync(FileAccessMode.ReadWrite))
        await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f);
    img.Source = new BitmapImage(new Uri(storageFolder.Path + "/" + i++ + ".png"));
    img.VerticalAlignment = VerticalAlignment.Stretch;
    ContainerCanvas.Children.Add(img);
    Canvas.SetTop(img, ScrollViewerContainer.VerticalOffset);
    Canvas.SetZIndex(img, 5);
}
于 2016-05-30T15:16:20.083 に答える
0

次の方法でキャンバスの背景をクリアしてみてください。

ds.Clear(Colors.White);

蛍光ペンは、その値を背景色で乗算するように見えるため、透明な背景では表示されません。

于 2016-04-04T08:25:25.713 に答える