Reputation: 31
I'm desperately trying to save a highlight stroke as a png. I'm using win2d for UWP to make this work.
It works well for strokes with 100% opacity, but when I set DrawAsHighlighter = true;
, the saved png is empty, fully transparent.
Here's my code :
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);
}
I've read it might be because of the highlight not being present in the visual tree but I'm really not sure about it.
By the way when I try to change the opacity of a color(attributes.Color = Color.FromArgb(128, 255, 0, 0)
), the inkcanvas doesn't apply the alpha, why ? Am I missing something ?
Upvotes: 3
Views: 966
Reputation: 31
I finally figured out how to make it work.
I simply added a new layer before calling DrawInk
and gave it an opacity, and got rid of the attributes.DrawAsHighlighter = true;
. Instead, I've made 1 inkCanvas with 0.5 opacity specially for the highlighter, looking like you're using a highlighter.
Here's the code :
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);
}
Upvotes: 0
Reputation: 2193
Try clearing the background of the canvas with:
ds.Clear(Colors.White);
The highlighter isn't visible on transparent backgrounds as it seems to multiply its value with the background color.
Upvotes: 0
Reputation: 264
You can't save DrawAsHighlighter ink to a bitmap format like .png - that's just fundamentally not a meaningful operation to be attempting.
Regular non-highlighter ink is drawn using standard alpha blending, so it is reasonable to write just these ink shapes into a bitmap format. You can later blend that bitmap over some other background image, and get the same result as if the ink had been drawn directly over that background.
For highlighter ink, however, the "blend over background" is a more complex operation, not just standard sourceover blending. So there is no such thing as a bitmap image that contains just this ink - you also have to provide a background in order for the appropriate blend to be carried out.
You have three options here:
Upvotes: 2