Esempio n. 1
0
        /// <summary>
        /// Share the current sketch as a JPEG with EXIF data
        /// </summary>
        /// <param name="parameter">the parameter is not used</param>
        /// <returns>an async task</returns>
        protected override async Task ExecuteAsync(object parameter)
        {
            var data = App.GetSketchData();

            var title = string.IsNullOrWhiteSpace(data.Name) ? "Sketch" : data.Name;

            var filename = Path.Combine(FileSystem.CacheDirectory, title + ".jpeg");

            using (var stream = File.Create(filename))
            {
                InkRenderer.RenderImage(data.Width, data.Height, data.BackgroundColor, data.InkStrokes.ToList(), stream, data.Width);
            }

            var photoLibrary = DependencyService.Get <IPhotoLibrary>();

            photoLibrary.AddExifData(filename);

            var request = new ShareFileRequest(title + " #Sketch360", new ShareFile(filename));

            await Share.RequestAsync(request).ConfigureAwait(false);

            var properties = new Dictionary <string, string>
            {
                ["width"]      = data.Width.ToString(CultureInfo.InvariantCulture),
                ["inkstrokes"] = data.InkStrokes.Count().ToString(CultureInfo.InvariantCulture),
                ["background"] = data.BackgroundColor.ToHex(),
                ["duration"]   = data.Duration.TotalMinutes.ToString(CultureInfo.InvariantCulture)
            };

            Analytics.TrackEvent("Share", properties);
        }
Esempio n. 2
0
        private async Task UpdateWebViewAsync()
        {
            var sketchData = App.GetSketchData();

            if (sketchData != null)
            {
                using (var stream = new MemoryStream())
                {
                    InkRenderer.RenderImage(
                        (int)InkCanvas.CanvasSize.Width,
                        (int)InkCanvas.CanvasSize.Height,
                        sketchData.BackgroundColor,
                        sketchData.InkStrokes.ToList(),
                        stream,
                        (int)InkCanvas.CanvasSize.Width);

                    stream.Seek(0, SeekOrigin.Begin);

                    InkCanvas.UpdateImageStream(stream);
                }

                //var totalMemory = GC.GetTotalMemory(false);

                // Collect all generations of memory.
                GC.Collect();

                //System.Diagnostics.Debug.WriteLine("Memory Collected after Rendering ink:   {0:N0}",
                //                  totalMemory- GC.GetTotalMemory(true));
            }

            var webView = FullPreview;// IsSpanned ? FullPreview : SplitPreview;

            await webView.UpdateWebViewAsync().ConfigureAwait(false);
        }
Esempio n. 3
0
        public void TestCreatePathPointsOnePoint()
        {
            var builder = new XInkStrokeBuilder();

            var inkPoints = new[] { new XInkPoint(new Point(0, 0), 1f, 0f, 0f, 0) };

            using var stroke = builder.CreateStrokeFromInkPoints(inkPoints);
            InkRenderer.CreatePathPoints(stroke);
        }
Esempio n. 4
0
        /// <summary>
        /// Export the image in a background task
        /// </summary>
        /// <param name="parameter">the parameter is not used</param>
        /// <returns>an async task</returns>
        protected override async Task ExecuteAsync(object parameter)
        {
            var data = App.GetSketchData();

            using var stream = new MemoryStream();
            InkRenderer.RenderImage(data.Width, data.Height, data.BackgroundColor, data.InkStrokes.ToList(), stream, data.Width);

            stream.Seek(0, SeekOrigin.Begin);

            var array = stream.ToArray();
            //https://github.com/Studyxnet/FilePicker-Plugin-for-Xamarin-and-Windows/
            var photoLibrary = DependencyService.Get <IPhotoLibrary>();
            var now          = DateTime.Now;
            var filename     = string.Format(
                CultureInfo.InvariantCulture,
                Resources.AppResources.DateFilenameFormat,
                string.IsNullOrWhiteSpace(data.Name) ? "Sketch360" : data.Name,
                now.Year,
                now.Month,
                now.Day,
                now.Hour,
                now.Minute,
                now.Second,
                "jpg");

            var chars = Path.GetInvalidFileNameChars();

            int index;

            var filenameChars = filename.ToCharArray();

            do
            {
                index = filename.IndexOfAny(chars);

                if (index >= 0)
                {
                    filenameChars[index] = '_';

                    filename = new string(filenameChars);
                }
            }while (index != -1);

            var saved = await photoLibrary.SavePhotoAsync(array, string.Empty, filename, Page).ConfigureAwait(false);

            var properties = new Dictionary <string, string>
            {
                ["saved"]      = saved.ToString(CultureInfo.InvariantCulture),
                ["width"]      = data.Width.ToString(CultureInfo.InvariantCulture),
                ["inkstrokes"] = data.InkStrokes.Count().ToString(CultureInfo.InvariantCulture),
                ["background"] = data.BackgroundColor.ToHex(),
                ["duration"]   = data.Duration.TotalMinutes.ToString(CultureInfo.InvariantCulture)
            };

            Analytics.TrackEvent("Image Exported", properties);
        }
Esempio n. 5
0
        protected override RawInkSample PipelinedRawToCalibratedConversion(Graphics g, RawInkSample sample, Size clientArea)
        {
            sample = base.PipelinedRawToCalibratedConversion(g, sample, clientArea);

            Point areaVector = new Point(clientArea.Width, clientArea.Height);

            InkRenderer.PixelToInkSpace(g, ref areaVector);

            sample.X -= areaVector.X >> 1;
            sample.Y -= areaVector.Y >> 1;

            return(sample);
        }
Esempio n. 6
0
        /// <summary>
        /// Updates the web view with the current sketch data
        /// </summary>
        /// <returns>an async task</returns>
        public async Task UpdateWebViewAsync()
        {
            if (!_navigated)
            {
                return;
            }

            var sketchData = App.GetSketchData();

            if (sketchData == null)
            {
                return;
            }

            await Task.Run(delegate
            {
                var base64 = InkRenderer.RenderImage(sketchData.Width, sketchData.Height, sketchData.InkStrokes, sketchData.BackgroundColor, 1024);

                var script = $"imageUpdated('{base64}');";

                if (Dispatcher == null)
                {
                    return;
                }

                Dispatcher.BeginInvokeOnMainThread(async delegate
                {
                    try
                    {
                        if (Preview == null)
                        {
                            return;
                        }

                        await Preview.EvaluateJavaScriptAsync(script).ConfigureAwait(false);
                        // There is a limit on the length of strings for the Preview.Eval() method.
                    }
                    catch (Exception e)
                    {
                        var properties = new Dictionary <string, string>
                        {
                            ["ScriptLength"] = script.Length.ToString(CultureInfo.InvariantCulture)
                        };

                        Crashes.TrackError(e, properties);
                    }
                });

                GC.Collect();
            }).ConfigureAwait(false);
        }
Esempio n. 7
0
        public void TestCreatePathPoints(double x1, double y1, double x2, double y2)
        {
            var builder = new XInkStrokeBuilder();

            var inkPoints = new[]
            {
                new XInkPoint(new Point(x1, y1), 1f, 0f, 0f, 0),
                new XInkPoint(new Point(x2, y2), 1f, 0f, 0f, 0),
            };

            using var stroke = builder.CreateStrokeFromInkPoints(inkPoints);
            var points = InkRenderer.CreatePathPoints(stroke);

            foreach (var item in points)
            {
                System.Diagnostics.Debug.WriteLine($"{item.X}, {item.Y}");
            }
        }
Esempio n. 8
0
        private static void AddJpegImage(ISketchData sketchData, ZipOutputStream zipStream)
        {
            var jpegEntry = new ZipEntry("sketch.jpeg")
            {
                DateTime = DateTime.UtcNow
            };

            zipStream.PutNextEntry(jpegEntry);

            using var memoryStream = new MemoryStream();
            InkRenderer.RenderImage(sketchData.Width, sketchData.Height, sketchData.BackgroundColor,
                                    sketchData.InkStrokes.ToList(), memoryStream, sketchData.Width);

            memoryStream.Seek(0, SeekOrigin.Begin);

            var buffer = new byte[4096];

            StreamUtils.Copy(memoryStream, zipStream, buffer);
        }
Esempio n. 9
0
 public MainViewModel()
 {
     _drawingData = new DrawingData();
     _inkRenderer = new InkRenderer();
     Scale        = new ReactiveProperty <double>(1.0);
     CanvasWidth  = _drawingData.ObserveProperty(x => x.CanvasWidth)
                    .CombineLatest(Scale, (a, b) => a * b)
                    .ToReadOnlyReactiveProperty();
     CanvasHeight = _drawingData.ObserveProperty(x => x.CanvasHeight)
                    .CombineLatest(Scale, (a, b) => a * b)
                    .ToReadOnlyReactiveProperty();
     ViewportOffsetX      = _drawingData.ToReactivePropertyAsSynchronized(x => x.OffsetX, x => x * Scale.Value, x => x / Scale.Value);
     ViewportOffsetY      = _drawingData.ToReactivePropertyAsSynchronized(x => x.OffsetY, x => x * Scale.Value, x => x / Scale.Value);
     ViewportWidth        = _drawingData.ToReactivePropertyAsSynchronized(x => x.ViewWidth, x => x * Scale.Value, x => x / Scale.Value);
     ViewportHeight       = _drawingData.ToReactivePropertyAsSynchronized(x => x.ViewHeight, x => x * Scale.Value, x => x / Scale.Value);
     MinimapImage         = new ReactiveProperty <IRandomAccessStream>();
     MinimapViewportScale = _drawingData.ObserveProperty(x => x.CanvasWidth)
                            .CombineLatest(_drawingData.ObserveProperty(x => x.CanvasHeight), ValueTuple.Create)
                            .Select(((double width, double height)x) =>
     {
         var scaleW = 100 / x.width;
         var scaleH = 100 / x.height;
         return(Math.Min(scaleW, scaleH));
     }).ToReadOnlyReactiveProperty();
Esempio n. 10
0
        /// <summary>
        /// Export the image in a background task
        /// </summary>
        /// <param name="parameter">the parameter is not used</param>
        /// <returns>an async task</returns>
        protected override async Task ExecuteAsync(object parameter)
        {
            var data = App.GetSketchData();

            using var stream = new MemoryStream();
            InkRenderer.RenderImage(data.Width, data.Height, data.BackgroundColor, data.InkStrokes.ToList(), stream, data.Width);

            stream.Seek(0, SeekOrigin.Begin);

            var array = stream.ToArray();
            //https://github.com/Studyxnet/FilePicker-Plugin-for-Xamarin-and-Windows/
            var photoLibrary = DependencyService.Get <IPhotoLibrary>();
            var now          = DateTime.Now;
            var filename     = string.Format(
                CultureInfo.InvariantCulture,
                Resources.AppResources.DateFilenameFormat,
                string.IsNullOrWhiteSpace(data.Name) ? "Sketch360" : data.Name,
                now.Year,
                now.Month,
                now.Day,
                now.Hour,
                now.Minute,
                now.Second,
                "jpg");

            var chars = Path.GetInvalidFileNameChars();

            int index;

            var filenameChars = filename.ToCharArray();

            do
            {
                index = filename.IndexOfAny(chars);

                if (index >= 0)
                {
                    filenameChars[index] = '_';

                    filename = new string(filenameChars);
                }
            }while (index != -1);

            var saved = await photoLibrary.SavePhotoAsync(array, string.Empty, filename, Page).ConfigureAwait(false);

            var introSketch = "No";

            var colors = 0;

            if (data.InkStrokes.Any())
            {
                var firstStrokeStart = data.InkStrokes.First().StrokeStartTime;

                if (firstStrokeStart.HasValue && firstStrokeStart.Value.Date == new DateTime(2020, 7, 29))
                {
                    // Intro Sketch has 254 strokes and was started on 7/29/2020
                    if (data.InkStrokes.Count() == 254)
                    {
                        introSketch = "Yes";
                    }
                    else
                    {
                        introSketch = "Modified";
                    }
                }

                colors = (from inkStroke in data.InkStrokes
                          group inkStroke by inkStroke.DrawingAttributes.Color
                          into c
                          select c.Key).Count();
            }

            var properties = new Dictionary <string, string>
            {
                ["saved"]       = saved.ToString(CultureInfo.InvariantCulture),
                ["width"]       = data.Width.ToString(CultureInfo.InvariantCulture),
                ["inkstrokes"]  = data.InkStrokes.Count().ToString(CultureInfo.InvariantCulture),
                ["background"]  = data.BackgroundColor.ToHex(),
                ["durationMin"] = data.Duration.TotalMinutes.ToString(CultureInfo.InvariantCulture),
                ["introSketch"] = introSketch,
                ["startDate"]   = data.Start.ToString("u", CultureInfo.InvariantCulture),
                ["colors"]      = colors.ToString("g", CultureInfo.InvariantCulture)
            };

            Analytics.TrackEvent("Image Exported", properties);
        }
Esempio n. 11
0
 public void TestCreatePathPointsEmpty()
 {
     using var inkStroke = new XInkStroke();
     InkRenderer.CreatePathPoints(inkStroke);
 }
Esempio n. 12
0
 public void CreatePathPointsNullStroke()
 {
     InkRenderer.CreatePathPoints(null);
 }