public async Task<Tuple<Stream, LoadingResult, ImageInformation>> Resolve(string identifier, TaskParameter parameters, CancellationToken token) { ImageSource source = parameters.Source; if (parameters.LoadingPlaceholderPath == identifier) source = parameters.LoadingPlaceholderSource; else if (parameters.ErrorPlaceholderPath == identifier) source = parameters.ErrorPlaceholderSource; var resolvedData = await Configuration.DataResolverFactory .GetResolver(identifier, source, parameters, Configuration) .Resolve(identifier, parameters, token); if (resolvedData?.Item1 == null) throw new FileNotFoundException(identifier); var svg = new SKSvg() { ThrowOnUnsupportedElement = false, }; SKPicture picture; using (var svgStream = resolvedData.Item1) { picture = svg.Load(resolvedData?.Item1); } using (var bitmap = new SKBitmap(200, 200, true)) using (var canvas = new SKCanvas(bitmap)) { float canvasMin = Math.Min(200, 200); float svgMax = Math.Max(svg.Picture.Bounds.Width, svg.Picture.Bounds.Height); float scale = canvasMin / svgMax; var matrix = SKMatrix.MakeScale(scale, scale); canvas.DrawPicture(picture, ref matrix); using (var image = SKImage.FromBitmap(bitmap)) { var stream = image.Encode()?.AsStream(); return new Tuple<Stream, LoadingResult, ImageInformation>(stream, resolvedData.Item2, resolvedData.Item3); } } }
public override void Dispose() { svg?.Dispose(); svg = null; }
private void Drop(object sender, DragEventArgs e) { if (e.Data.Contains(DataFormats.FileNames)) { var fileName = e.Data.GetFileNames()?.FirstOrDefault(); if (!string.IsNullOrWhiteSpace(fileName)) { if (sender == _svgSourceDockPanel) { var svg = new SvgSource(); #if USE_PICTURE var document = SKSvg.Open(fileName); if (document != null) { var picture = SKSvg.ToModel(document); if (picture != null) { svg.Picture = picture; _svgSourceImage.Source = new SvgImage() { Source = svg }; } } #else var picture = svg.Load(fileName); if (picture != null) { _svgSourceImage.Source = new SvgImage() { Source = svg }; } #endif } if (sender == _svgResourceDockPanel) { #if USE_PICTURE var svg = new SvgSource(); var document = SKSvg.Open(fileName); if (document != null) { var picture = SKSvg.ToModel(document); if (picture != null) { svg.Picture = picture; _svgResourceImage.Source = new SvgImage() { Source = svg }; } } #else var svg = new SvgSource(); var picture = svg.Load(fileName); if (picture != null) { _svgResourceImage.Source = new SvgImage() { Source = svg }; } #endif } } } }
public VectorImage(string filename) : base(filename) { svg = new SKSvg(); svg.Load(filename); }
public override void Resize(string sourceFile, string destinationFile, ImageAsset asset, OutputConfig outputConfig) { int sourceNominalWidth = asset.Width; int sourceNominalHeight = asset.Height; double resizeRatio = outputConfig.Ratio; // For SVG's we can optionally change the fill color on all paths if (!string.IsNullOrEmpty(outputConfig.FillColor)) { var svgText = File.ReadAllText(sourceFile); var matches = Regex.Matches(svgText, rxFill); foreach (Match match in matches) { var fillGroup = match.Groups?["fill"]; if (fillGroup != null) { // Replace the matched rx group with our override fill color var a = svgText.Substring(0, fillGroup.Index); var b = svgText.Substring(fillGroup.Index + fillGroup.Length); svgText = a + outputConfig.FillColor.TrimEnd(';') + ";" + b; } } // Write our changes out to a temp file so we don't alter the original var tempFile = Path.GetTempFileName(); File.WriteAllText(tempFile, svgText); sourceFile = tempFile; } var svg = new SKSvg(); svg.Load(sourceFile); // Find the actual size of the SVG var sourceActualWidth = svg.Picture.CullRect.Width; var sourceActualHeight = svg.Picture.CullRect.Height; // Figure out what the ratio to convert the actual image size to the nominal size is var nominalRatio = Math.Max((double)sourceNominalWidth / (double)sourceActualWidth, (double)sourceNominalHeight / (double)sourceActualHeight); // Multiply nominal ratio by the resize ratio to get our final ratio we actually adjust by var adjustRatio = nominalRatio * resizeRatio; // Figure out our scaled width and height to make a new canvas for var scaledWidth = sourceActualWidth * adjustRatio; var scaledHeight = sourceActualHeight * adjustRatio; // Make a canvas of the target size to draw the svg onto var bmp = new SKBitmap((int)scaledWidth, (int)scaledHeight); var canvas = new SKCanvas(bmp); // Make a matrix to scale the SVG var matrix = SKMatrix.MakeScale((float)adjustRatio, (float)adjustRatio); canvas.Clear(SKColors.Transparent); // Draw the svg onto the canvas with our scaled matrix canvas.DrawPicture(svg.Picture, ref matrix); // Save the op canvas.Save(); // Export the canvas var img = SKImage.FromBitmap(bmp); var data = img.Encode(SKImageEncodeFormat.Png, 100); using (var fs = File.Open(destinationFile, FileMode.Create)) data.SaveTo(fs); }
public async Task CreateAsset(string filepath, string filename, string destinationDirectory, int quality, string postfix) { var resourceTypes = new Dictionary <AndroidResourceType, float> { // Scale factors { AndroidResourceType.LDPI, 0.75f }, { AndroidResourceType.MDPI, 1 }, { AndroidResourceType.HDPI, 1.5f }, { AndroidResourceType.XHDPI, 2f }, { AndroidResourceType.XXHDPI, 3f }, { AndroidResourceType.XXXHDPI, 4f } }; foreach (var resourceType in resourceTypes) { try { var name = Enum.GetName(typeof(AndroidResourceType), resourceType.Key); var resourceDirectoryName = string.IsNullOrEmpty(postfix) ? $"drawable-{name.ToLowerInvariant()}" : $"drawable-{name.ToLowerInvariant()}-{postfix}"; var svg = new SKSvg(); try { svg.Load(filepath); } catch (Exception e) { Console.WriteLine($"Unexpected error when parsing asset: {filepath}"); Console.WriteLine("Error: " + e.Message); Console.WriteLine("Exiting with error 1"); Environment.Exit(1); } var width = (int)(svg.CanvasSize.Width * resourceType.Value); var height = (int)(svg.CanvasSize.Height * resourceType.Value); // Cheap clamp if (width < 1) { width = 1; } if (height < 1) { height = 1; } var filenameWithExtension = $"{filename}.png"; var resourceDir = Path.Combine(destinationDirectory, resourceDirectoryName); if (!Directory.Exists(resourceDir)) { Directory.CreateDirectory(resourceDir); } var finalPath = Path.Combine(resourceDir, filenameWithExtension); await PngHelper.GeneratePng(width, height, filepath, finalPath, quality); Console.WriteLine($"Successfully created asset: {finalPath}"); } catch (Exception e) { Console.WriteLine($"Failed to generate asset: {filename}"); Console.WriteLine("Error: " + e.Message); Console.WriteLine("Exiting with error 1"); Environment.Exit(1); } } }
public void Dispose() { svg?.Dispose(); svg = null; }
private static void ExtractImageFromStream(string url, Size desiredSize, Stream inputStream, Stream imageStream) { if (IsSvg(url)) { using (var svg = new SKSvg()) { try { svg.Load(inputStream); } catch (Exception exception) { Logger.Warning(exception, $"Something is wrong with: \"{url}\"."); return; } var skPicture = svg.Picture; var imageInfo = new SKImageInfo((int)desiredSize.Width, (int)desiredSize.Height); using (var surface = SKSurface.Create(imageInfo)) { using (var canvas = surface.Canvas) { // calculate the scaling need to fit to desired size var scaleX = desiredSize.Width / skPicture.CullRect.Width; var scaleY = desiredSize.Height / skPicture.CullRect.Height; var matrix = SKMatrix.MakeScale((float)scaleX, (float)scaleY); // draw the svg canvas.Clear(SKColors.Transparent); canvas.DrawPicture(skPicture, ref matrix); canvas.Flush(); using (var data = surface.Snapshot()) { using (var pngImage = data.Encode(SKEncodedImageFormat.Png, 100)) { pngImage.SaveTo(imageStream); } } } } } } else { var bitmap = SKBitmap.Decode(inputStream); if (bitmap != null) { var resizeInfo = GetResizeSkImageInfo(desiredSize, bitmap); using (var resizedBitmap = bitmap.Resize(resizeInfo, SKFilterQuality.High)) { bitmap.Dispose(); using (var image = SKImage.FromBitmap(resizedBitmap)) { using (var data = image.Encode(SKEncodedImageFormat.Png, 100)) { data.SaveTo(imageStream); } } } } } }