/// <inheritdoc/> public void Export(IPlotModel model, Stream stream) { using var bitmap = new SKBitmap(this.Width, this.Height); using (var canvas = new SKCanvas(bitmap)) using (var context = new SkiaRenderContext { RenderTarget = RenderTarget.PixelGraphic, SkCanvas = canvas }) { canvas.Clear(SKColors.White); var dpiScale = this.Dpi / 96; context.DpiScale = dpiScale; model.Update(true); var backgroundColor = model.Background; // jpg doesn't support transparency if (!backgroundColor.IsVisible()) { backgroundColor = OxyColors.White; } canvas.Clear(backgroundColor.ToSKColor()); model.Render(context, new OxyRect(0, 0, this.Width / dpiScale, this.Height / dpiScale)); } using var skStream = new SKManagedWStream(stream); SKPixmap.Encode(skStream, bitmap, SKEncodedImageFormat.Jpeg, this.Quality); }
public void Measure() { var writer = new BarcodeWriter { // Format = BarcodeFormat.EAN_13, Format = BarcodeFormat.AZTEC, Options = new AztecEncodingOptions { Width = 1000, Height = 1000 } }; var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Restart(); writer.Write("123456789012"); stopWatch.Stop(); Console.WriteLine(stopWatch.Elapsed); stopWatch.Restart(); writer.Write("123456789012"); stopWatch.Stop(); Console.WriteLine(stopWatch.Elapsed); var bitmap = writer.Write("123456789012"); using (var fileStream = System.IO.File.Create("C:\\ZXing.Net\\test.png")) using (var dst = new SKManagedWStream(fileStream)) { SKPixmap.Encode(dst, bitmap, SKEncodedImageFormat.Png, 100); } }
/// <summary> /// Create a thumb collage. /// </summary> /// <param name="paths">The paths of the images to use in the collage.</param> /// <param name="outputPath">The path at which to place the resulting image.</param> /// <param name="width">The desired width of the collage.</param> /// <param name="height">The desired height of the collage.</param> /// <param name="libraryName">The name of the library to draw on the collage.</param> public void BuildThumbCollage(string[] paths, string outputPath, int width, int height, string?libraryName) { using var bitmap = BuildThumbCollageBitmap(paths, width, height, libraryName); using var outputStream = new SKFileWStream(outputPath); using var pixmap = new SKPixmap(new SKImageInfo(width, height), bitmap.GetPixels()); pixmap.Encode(outputStream, GetEncodedFormat(outputPath), 90); }
private static MemoryStream CreateCallbackImage(City city) { SKRect bounds; using (SKPaint paint = new SKPaint()) { paint.Color = new SKColor((byte)Random.Next(0, 256), (byte)Random.Next(0, 256), (byte)Random.Next(0, 256)); paint.Typeface = SKTypeface.FromFamilyName(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); paint.TextSize = 20; using (SKPath textPath = paint.GetTextPath(city.Name, 0, 0)) { // Set transform to center and enlarge clip path to window height textPath.GetTightBounds(out bounds); } using (var bitmap = new SKBitmap((int)(bounds.Width + 1), (int)(bounds.Height + 1))) using (var canvas = new SKCanvas(bitmap)) { canvas.Clear(); canvas.DrawText(city.Name, -bounds.Left, -bounds.Top, paint); var memStream = new MemoryStream(); using (var wstream = new SKManagedWStream(memStream)) { SKPixmap.Encode(wstream, bitmap, SKEncodedImageFormat.Png, 100); } return(memStream); } } }
/// <summary> /// Create a square collage. /// </summary> /// <param name="paths">The paths of the images to use in the collage.</param> /// <param name="outputPath">The path at which to place the resulting collage image.</param> /// <param name="width">The desired width of the collage.</param> /// <param name="height">The desired height of the collage.</param> public void BuildSquareCollage(IReadOnlyList <string> paths, string outputPath, int width, int height) { using var bitmap = BuildSquareCollageBitmap(paths, width, height); using var outputStream = new SKFileWStream(outputPath); using var pixmap = new SKPixmap(new SKImageInfo(width, height), bitmap.GetPixels()); pixmap.Encode(outputStream, GetEncodedFormat(outputPath), 90); }
async void OnSaveButtonClicked(object sender, EventArgs e) { SKEncodedImageFormat imageFormat = (SKEncodedImageFormat)formatPicker.SelectedItem; int quality = (int)qualitySlider.Value; using (MemoryStream memStream = new MemoryStream()) { using (SKManagedWStream wstream = new SKManagedWStream(memStream)) { bool result = pixmap.Encode(wstream, imageFormat, quality); byte[] data = memStream.ToArray(); if (data == null || data.Length == 0) { statusLabel.Text = "Encode failed"; } else { bool success = await DependencyService.Get <IPhotoPickerService>().SavePhotoAsync(data, folderNameEntry.Text, fileNameEntry.Text); if (!success) { statusLabel.Text = "Save failed"; } else { statusLabel.Text = "Save succeeded"; } } } } }
public override void Run() { // 1. Opening the PDF file... string filePath = PromptFileChoice("Please select a PDF file"); using (var file = new File(filePath)) { Document document = file.Document; Pages pages = document.Pages; // 2. Page rasterization. int pageIndex = PromptPageChoice("Select the page to render", pages.Count); Page page = pages[pageIndex]; SKSize imageSize = new SKSize(page.RotatedBox.Width * 2.5F, page.RotatedBox.Height * 2.5F); Renderer renderer = new Renderer(); var image = renderer.Render(page, imageSize); // 3. Save the page image! using (var stream = new SKFileWStream(GetOutputPath("ContentRenderingSample.png"))) { SKPixmap.Encode(stream, image, SKEncodedImageFormat.Png, 100); }; } }
static void Main(string[] args) { var examples = new IExampleRunner[] { new CannonTest(), new Clock(), new SingleSphereExample(), new MultipleSphereTest(), new ShadedSphere(), new CameraTest(), new DualLightCameraTest(), new PlaneExample(), new PatternExample(), }; var outputDirectory = Path.Combine(new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.Parent.Parent.ToString(), "Examples"); var examplesToRun = examples.Select((x, index) => new { Example = x, index }) .Skip(examples.Length - 1); foreach (var item in examplesToRun) { var filename = Path.Combine(outputDirectory, $"{item.index:00}_{item.Example.GetType().Name}.png"); var stopwatch = Stopwatch.StartNew(); var canvas = item.Example.Run(); stopwatch.Stop(); using var file = new SKFileWStream(filename); using var bitmap = canvas.RenderToBitmap(); SKPixmap.Encode(file, bitmap, SKEncodedImageFormat.Png, 100); Console.WriteLine($"Canvas rendered in {stopwatch.ElapsedMilliseconds:N}ms"); } }
public byte[] ResizeTo(byte[] sourceImageData, int size) { using (var ms = new MemoryStream(sourceImageData)) using (var inputStream = new SKManagedStream(ms, false)) using (var codec = SKCodec.Create(inputStream)) { var sourceBitmap = SKBitmap.Decode(codec); if (codec.EncodedOrigin != SKEncodedOrigin.TopLeft) { sourceBitmap = RotateAndFlip(sourceBitmap, codec.EncodedOrigin); } var sourceSize = Math.Max(sourceBitmap.Width, sourceBitmap.Height); var ratio = size / (double)sourceSize; using (var targetBitmap = new SKBitmap(new SKImageInfo((int)(sourceBitmap.Width * ratio), (int)(sourceBitmap.Height * ratio)))) using (var targetMemoryStream = new MemoryStream()) using (var thumbnailStream = new SKManagedWStream(targetMemoryStream)) { sourceBitmap.ScalePixels(targetBitmap, SKFilterQuality.High); SKPixmap.Encode(thumbnailStream, targetBitmap, SKEncodedImageFormat.Jpeg, 85); thumbnailStream.Flush(); sourceBitmap.Dispose(); return(targetMemoryStream.ToArray()); } } }
public void Save(string path) { using (var stream = File.Create(path)) using (var skiaStream = new SKManagedWStream(stream)) { SKPixmap.Encode(skiaStream, _skBitmap, SKEncodedImageFormat.Png, 100); } }
/// <summary> /// Generate a splashscreen. /// </summary> /// <param name="posters">The poster paths.</param> /// <param name="backdrops">The landscape paths.</param> /// <param name="outputPath">The output path.</param> public void GenerateSplash(IReadOnlyList <string> posters, IReadOnlyList <string> backdrops, string outputPath) { using var wall = GenerateCollage(posters, backdrops); using var transformed = Transform3D(wall); using var outputStream = new SKFileWStream(outputPath); using var pixmap = new SKPixmap(new SKImageInfo(FinalWidth, FinalHeight), transformed.GetPixels()); pixmap.Encode(outputStream, StripCollageBuilder.GetEncodedFormat(outputPath), 90); }
public override void Save(Stream stream, ImageFormat format, int quality = 100) { using var wstream = new SKManagedWStream(stream, false); using var pixmap = new SKPixmap(); if (skBitmap.PeekPixels(pixmap)) { pixmap.Encode(wstream, (SKEncodedImageFormat)format, quality); } }
/// <summary> /// Create a square collage. /// </summary> /// <param name="paths">The paths of the images to use in the collage.</param> /// <param name="outputPath">The path at which to place the resulting collage image.</param> /// <param name="width">The desired width of the collage.</param> /// <param name="height">The desired height of the collage.</param> public void BuildSquareCollage(string[] paths, string outputPath, int width, int height) { using (var bitmap = BuildSquareCollageBitmap(paths, width, height)) using (var outputStream = new SKFileWStream(outputPath)) using (var pixmap = new SKPixmap(new SKImageInfo(width, height), bitmap.GetPixels())) { pixmap.Encode(outputStream, GetEncodedFormat(outputPath), 90); } }
public static void SaveBitmap( [InputPin(PropertyMode = PropertyMode.Never)] SKBitmap bitmap, [InputPin(PropertyMode = PropertyMode.Default, ResolvePath = true)] string path, [InputPin(PropertyMode = PropertyMode.Default)] SKEncodedImageFormat format = SKEncodedImageFormat.Png, [InputPin(PropertyMode = PropertyMode.Default)] int quality = 95 ) { using (var stream = new SKFileWStream(path)) { SKPixmap.Encode(stream, bitmap, format, quality); } }
public static byte[] PngToWebp(byte[] img) { using (var stream = new MemoryStream(img)) using (var bitmap = SKBitmap.Decode(stream)) { using (MemoryStream memStream = new MemoryStream()) using (SKManagedWStream wstream = new SKManagedWStream(memStream)) { SKPixmap.Encode(wstream, bitmap, SKEncodedImageFormat.Webp, 100); return(memStream.ToArray()); } } }
public static IWritable EncodeBitmap( [InputPin(PropertyMode = PropertyMode.Never)] SKBitmap bitmap, [InputPin(PropertyMode = PropertyMode.Default)] SKEncodedImageFormat format = SKEncodedImageFormat.Png, [InputPin(PropertyMode = PropertyMode.Default)] int quality = 95 ) { return(Writable.Create(stream => { using (var skStream = new SKManagedWStream(stream)) { SKPixmap.Encode(skStream, bitmap, format, quality); } })); }
public void DecompressByteArray( [CombinatorialValues( SKColorType.Bgra8888, SKColorType.Rgba8888, SKColorType.Rgb888x)] SKColorType format) { foreach (var data in TestUtils.GetTestImagesData("*.jpg")) { var result = this.decompressor.Decompress(data.Item2, format, TJFlags.None); Assert.NotNull(result); var file = Path.Combine(this.OutDirectory, $"{Path.GetFileNameWithoutExtension(data.Item1)}_{format}.bmp"); using var s = new SKFileWStream(file); SKPixmap.Encode(s, result, SKEncodedImageFormat.Bmp, 100); } }
private Response RenderMap(dynamic parameters) { var gameServer = this.servers.OfType <IGameServer>().FirstOrDefault(s => s.Id == (byte)parameters.serverId); var map = gameServer?.ServerInfo.Maps.FirstOrDefault(m => m.MapNumber == (short)parameters.mapId); if (map == null) { Log.Warn($"requested map not available. map number: {parameters.mapId}; server id: {parameters.serverId}"); return(null); } var terrain = new GameMapTerrain(map.MapName, map.TerrainData); using (var bitmap = new SkiaSharp.SKBitmap(0x100, 0x100)) { for (int y = 0; y < 0x100; y++) { for (int x = 0; x < 0x100; x++) { var color = SKColors.Black; if (terrain.SafezoneMap[y, x]) { color = SKColors.Gray; } else if (terrain.WalkMap[y, x]) { color = SKColors.SpringGreen; } bitmap.SetPixel(x, y, color); } } using (var memoryStream = new SKDynamicMemoryWStream()) { if (SKPixmap.Encode(memoryStream, bitmap, SKEncodedImageFormat.Png, 100)) { return(this.Response.FromStream(memoryStream.DetachAsData().AsStream, "image/png")); } } return(null); } }
/// <inheritdoc/> public void Export(IPlotModel model, Stream stream) { using var bitmap = new SKBitmap(this.Width, this.Height); using (var canvas = new SKCanvas(bitmap)) using (var context = new SkiaRenderContext { RenderTarget = RenderTarget.PixelGraphic, SkCanvas = canvas, UseTextShaping = this.UseTextShaping }) { var dpiScale = this.Dpi / 96; context.DpiScale = dpiScale; model.Update(true); canvas.Clear(model.Background.ToSKColor()); model.Render(context, new OxyRect(0, 0, this.Width / dpiScale, this.Height / dpiScale)); } using var skStream = new SKManagedWStream(stream); SKPixmap.Encode(skStream, bitmap, SKEncodedImageFormat.Png, 0); }
public void SaveImage(SKBitmap image, string filepath) { SKEncodedImageFormat format; if (filepath.EndsWith("png")) { format = SKEncodedImageFormat.Png; } else if (filepath.EndsWith("jpg")) { format = SKEncodedImageFormat.Jpeg; } else //else if (filepath.EndsWith("webp")) { throw new InvalidOperationException("webp not supported"); } SKPixmap.Encode(new SKFileWStream(filepath), image, format, DefaultQuality); }
private void SaveThumbnail(IEntity entity, SKBitmap thumbnail) { using (var dataStrem = new MemoryStream()) using (var outputStream = new SKManagedWStream(dataStrem)) { var isEncoded = SKPixmap.Encode( outputStream, thumbnail, SKEncodedImageFormat.Jpeg, SavedThumbnailQuaity); if (!isEncoded) { return; } var value = new ImageValue(dataStrem.ToArray()); var newEntity = entity.SetAttribute(new Attribute( ExifAttributeReaderFactory.Thumbnail, value, AttributeSource.Metadata)); _storage.StoreThumbnail(newEntity); } }
private Stream RenderMap(IGameMapInfo map) { var terrain = new GameMapTerrain(map.MapName, map.TerrainData); using (var bitmap = new SkiaSharp.SKBitmap(0x100, 0x100)) { for (int y = 0; y < 0x100; y++) { for (int x = 0; x < 0x100; x++) { var color = SKColors.Black; if (terrain.SafezoneMap[y, x]) { color = SKColors.Gray; } else if (terrain.WalkMap[y, x]) { color = SKColors.SpringGreen; } else { // we use the default color. } bitmap.SetPixel(x, y, color); } } using (var memoryStream = new SKDynamicMemoryWStream()) { if (SKPixmap.Encode(memoryStream, bitmap, SKEncodedImageFormat.Png, 100)) { return(memoryStream.DetachAsData().AsStream()); } } return(null); } }
/// <summary> /// Handles any required preprocessing of the captured image. /// </summary> /// <param name="camera">The camera that the snapshot is from.</param> /// <param name="snapshot">The image data.</param> /// <returns>A byte array of the image.</returns> private byte[] PreProcessSnapshot(Camera camera, byte[] snapshot) { if (camera.Rotate == 0) { return(snapshot); } Stopwatch stopwatch = Stopwatch.StartNew(); // Load the bitmap & rotate the image SKBitmap bitmap = SKBitmap.Decode(new MemoryStream(snapshot)); _logger.LogInformation($"{camera.Name}: Rotating image {camera.Rotate} degrees."); bitmap = Rotate(bitmap, camera.Rotate); using (SKPixmap pixmap = bitmap.PeekPixels()) using (SKData data = pixmap.Encode(SKEncodedImageFormat.Jpeg, 100)) { _logger.LogInformation($"{camera.Name}: Image preprocessing complete ({stopwatch.ElapsedMilliseconds}ms)."); return(data.ToArray()); } }
static void Run(Options options) { SKBitmap inputBitmap = SKBitmap.Decode(options.InputFile); if (inputBitmap != null) { try { Console.WriteLine("Compressing image..."); Atom[][,] compressedData = CompressRGBBitmap(inputBitmap, options.RangeSize, options.DomainSize, options.Contrast); WriteCompressedDataToFile(compressedData, options.OutputFile); inputBitmap.Dispose(); Console.Write("Compression completed!"); } catch (Exception) { Console.Write("An error occured while compressing the image. Double check your parameters and try again."); } } else { try { Console.WriteLine("Decompressing image..."); Atom[][,] compressedData = ReadCompressedDataFromFile(options.InputFile); using (SKBitmap outputBitmap = DecompressRGBBitmap(compressedData, options.RangeSize, options.DomainSize, options.Iterations)) using (SKFileWStream fileHandle = new SKFileWStream(options.OutputFile)) { SKPixmap.Encode(fileHandle, outputBitmap, SKEncodedImageFormat.Png, 100); } Console.Write("Decompression completed!"); } catch (Exception) { Console.Write("An error occured while decompressing the image. Double check your parameters and try again."); } } }
private MemoryStream GenerateImageBySkiaSharp(BarcodeFormat format, string code, int width, int height) { var writer = new BarcodeWriter(); writer.Format = format; EncodingOptions options = new EncodingOptions() { Width = width, Height = height, Margin = 2, PureBarcode = false }; writer.Options = options; if (format == BarcodeFormat.QR_CODE) { var qrOption = new QrCodeEncodingOptions() { DisableECI = true, CharacterSet = "UTF-8", Width = width, Height = height, Margin = 2 }; writer.Options = qrOption; } var bitmap = writer.Write(code); var ms = new MemoryStream(); using (SKManagedWStream skStream = new SKManagedWStream(ms)) { SKPixmap.Encode(skStream, bitmap, SKEncodedImageFormat.Jpeg, 100); //bitmap.Encode(skStream,SKEncodedImageFormat.Jpeg,100); } return(ms); }
public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation?orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { if (string.IsNullOrWhiteSpace(inputPath)) { throw new ArgumentNullException(nameof(inputPath)); } if (string.IsNullOrWhiteSpace(inputPath)) { throw new ArgumentNullException(nameof(outputPath)); } var skiaOutputFormat = GetImageFormat(selectedOutputFormat); var hasBackgroundColor = !string.IsNullOrWhiteSpace(options.BackgroundColor); var hasForegroundColor = !string.IsNullOrWhiteSpace(options.ForegroundLayer); var blur = options.Blur ?? 0; var hasIndicator = options.AddPlayedIndicator || options.UnplayedCount.HasValue || !options.PercentPlayed.Equals(0); using (var bitmap = GetBitmap(inputPath, options.CropWhiteSpace, autoOrient, orientation)) { if (bitmap == null) { throw new ArgumentOutOfRangeException(string.Format("Skia unable to read image {0}", inputPath)); } var originalImageSize = new ImageDimensions(bitmap.Width, bitmap.Height); if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize) && !autoOrient) { // Just spit out the original file if all the options are default return(inputPath); } var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize); var width = newImageSize.Width; var height = newImageSize.Height; using (var resizedBitmap = new SKBitmap(width, height, bitmap.ColorType, bitmap.AlphaType)) { // scale image bitmap.ScalePixels(resizedBitmap, SKFilterQuality.High); // If all we're doing is resizing then we can stop now if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator) { Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var outputStream = new SKFileWStream(outputPath)) using (var pixmap = new SKPixmap(new SKImageInfo(width, height), resizedBitmap.GetPixels())) { pixmap.Encode(outputStream, skiaOutputFormat, quality); return(outputPath); } } // create bitmap to use for canvas drawing used to draw into bitmap using (var saveBitmap = new SKBitmap(width, height)) //, bitmap.ColorType, bitmap.AlphaType)) using (var canvas = new SKCanvas(saveBitmap)) { // set background color if present if (hasBackgroundColor) { canvas.Clear(SKColor.Parse(options.BackgroundColor)); } // Add blur if option is present if (blur > 0) { // create image from resized bitmap to apply blur using (var paint = new SKPaint()) using (var filter = SKImageFilter.CreateBlur(blur, blur)) { paint.ImageFilter = filter; canvas.DrawBitmap(resizedBitmap, SKRect.Create(width, height), paint); } } else { // draw resized bitmap onto canvas canvas.DrawBitmap(resizedBitmap, SKRect.Create(width, height)); } // If foreground layer present then draw if (hasForegroundColor) { if (!double.TryParse(options.ForegroundLayer, out double opacity)) { opacity = .4; } canvas.DrawColor(new SKColor(0, 0, 0, (byte)((1 - opacity) * 0xFF)), SKBlendMode.SrcOver); } if (hasIndicator) { DrawIndicator(canvas, width, height, options); } Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var outputStream = new SKFileWStream(outputPath)) { using (var pixmap = new SKPixmap(new SKImageInfo(width, height), saveBitmap.GetPixels())) { pixmap.Encode(outputStream, skiaOutputFormat, quality); } } } } } return(outputPath); }
public byte[] GetImage(string referenceName, int zoomLevel, int chunk) { var refer = _service._references.First(r => r.Name == referenceName); var height = (_service._histograms[refer.Name].Max() + 1) * 15; using var surface = SKSurface.Create(new SKImageInfo(WIDTH, height)); using SKCanvas canvas = surface.Canvas; canvas.Clear(); using SKPaint paint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Black, StrokeWidth = 1 }; using SKPaint fillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = SKColors.Blue, StrokeWidth = 1 }; using SKPaint reverseFillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = SKColors.Red, StrokeWidth = 1 }; var startY = 7; var list = new List <long> { 0 }; using var reader = new StreamReader($"{_service._references.IndexOf(refer)}.tmp"); string line; while ((line = reader.ReadLine()) != null) { var splitLine = line.Split('\t'); var read = new SamFile { QueryName = splitLine[0], ReferenceName = splitLine[1], StartingPos = int.Parse(splitLine[2]), DrawExpressions = DataService.GetDrawExpressions(splitLine[3]), Reverse = bool.Parse(splitLine[4]) }; var realStartingX = zoomLevel * read.StartingPos; if (realStartingX >= (chunk + 1) * WIDTH) { break; } var index = list.FindIndex(i => realStartingX > i + 1); var y = startY * (index != -1 ? index : list.Count); var lineLength = read.DrawExpressions.Sum(de => de.Length) * zoomLevel; if (index == -1) { list.Add(realStartingX + lineLength); } else { list[index] = realStartingX + lineLength; } realStartingX -= chunk * WIDTH; if (realStartingX < 0 && realStartingX + lineLength < 0) { continue; } canvas.DrawLine(new SKPoint(realStartingX, y + 3), new SKPoint(realStartingX + lineLength, y + 3), paint); var currentX = realStartingX; foreach (var draw in read.DrawExpressions) { if (draw.Type == DrawType.Rectangle) { canvas.DrawRect(currentX, y, draw.Length * zoomLevel, 5, read.Reverse ? reverseFillPaint : fillPaint); canvas.DrawRect(currentX, y, draw.Length * zoomLevel, 5, paint); } currentX += draw.Length * zoomLevel; } canvas.Flush(); } var width = (chunk + 1) * WIDTH * zoomLevel > refer.Length * zoomLevel ? refer.Length * zoomLevel % WIDTH : WIDTH; var realHeight = 7 * (list.Count + 1); SKPixmap pixmap = surface.Snapshot().Subset(SKRectI.Create(0, 0, width, realHeight)).PeekPixels(); SKData data; if (realHeight > 15000) { data = pixmap.Encode(SKPngEncoderOptions.Default); } else { var options = new SKWebpEncoderOptions(SKWebpEncoderCompression.Lossless, 100); data = pixmap.Encode(options); } return(data.ToArray()); }
private static void ConvertFile(string file) { SKColorType colorType; using (var image = Pfim.FromFile(file)) { var newData = image.Data; var newDataLen = image.DataLen; var stride = image.Stride; switch (image.Format) { case ImageFormat.Rgb8: colorType = SKColorType.Gray8; break; case ImageFormat.R5g6b5: // color channels still need to be swapped colorType = SKColorType.Rgb565; break; case ImageFormat.Rgba16: // color channels still need to be swapped colorType = SKColorType.Argb4444; break; case ImageFormat.Rgb24: // Skia has no 24bit pixels, so we upscale to 32bit var pixels = image.DataLen / 3; newDataLen = pixels * 4; newData = new byte[newDataLen]; for (int i = 0; i < pixels; i++) { newData[i * 4] = image.Data[i * 3]; newData[i * 4 + 1] = image.Data[i * 3 + 1]; newData[i * 4 + 2] = image.Data[i * 3 + 2]; newData[i * 4 + 3] = 255; } stride = image.Width * 4; colorType = SKColorType.Bgra8888; break; case ImageFormat.Rgba32: colorType = SKColorType.Bgra8888; break; default: throw new ArgumentException($"Skia unable to interpret pfim format: {image.Format}"); } var imageInfo = new SKImageInfo(image.Width, image.Height, colorType); var handle = GCHandle.Alloc(newData, GCHandleType.Pinned); var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(newData, 0); using (var data = SKData.Create(ptr, newDataLen, (address, context) => handle.Free())) using (var skImage = SKImage.FromPixelData(imageInfo, data, stride)) using (var bitmap = SKBitmap.FromImage(skImage)) using (var fs = File.Create(Path.ChangeExtension(file, ".png"))) using (var wstream = new SKManagedWStream(fs)) { var success = SKPixmap.Encode(wstream, bitmap, SKEncodedImageFormat.Png, 95); Console.WriteLine(success ? "Image converted successfully" : "Image unsuccessful"); } } }
private static async Task CompareVisualResult(double totalWidth, double totalHeight, List <RenderFinishedEventArgs> result, string referenceFileName, Uint8Array referenceFileData, string?message) { // TODO: get Skia to render like Chrome // https://github.com/mono/SkiaSharp/issues/1253 return; SKBitmap finalBitmap; using (var finalImageSurface = SKSurface.Create(new SKImageInfo((int)totalWidth, (int)totalHeight, SKImageInfo.PlatformColorType, SKAlphaType.Premul))) { var point = new SKPoint(); var rowHeight = 0; foreach (var partialResult in result) { var partialCanvas = partialResult.RenderResult; if (partialCanvas is SKImage img) { finalImageSurface.Canvas.DrawImage(img, point); if (partialResult.Height > rowHeight) { rowHeight = img.Height; } point.X += img.Width; if (point.X >= totalWidth) { point.X = 0; point.Y += rowHeight; rowHeight = 0; } } } using var finalImage = finalImageSurface.Snapshot(); finalBitmap = SKBitmap.FromImage(finalImage); } var finalImageFileName = Path.ChangeExtension(referenceFileName, ".new.png"); using (finalBitmap) { var dir = Path.GetDirectoryName(finalImageFileName); Directory.CreateDirectory(dir); using (var fileStream = new SKFileWStream(finalImageFileName)) { SKPixmap.Encode(fileStream, finalBitmap, SKEncodedImageFormat.Png, 100); } SKBitmap referenceBitmap; using (var data = SKData.CreateCopy(referenceFileData.Buffer.Raw)) { referenceBitmap = SKBitmap.Decode(data); } using (referenceBitmap) { var compareResult = PixelMatch.Run(finalBitmap, referenceBitmap, new PixelMatchOptions { Threshold = 0.8, IncludeAntiAlias = false, IgnoreTransparent = true, CreateOutputImage = true }); using (compareResult.Output) { Assert.IsTrue(compareResult.SizesMatch, "Dimensions differ"); if (compareResult.Mismatch > 0.01) { var diffImageName = Path.ChangeExtension(referenceFileName, ".diff.png"); using (var fileStream = new SKFileWStream(diffImageName)) { SKPixmap.Encode(fileStream, compareResult.Output, SKEncodedImageFormat.Png, 100); } Assert.Fail( $"Difference between original and new image is too big: {compareResult.Mismatch:P}, {compareResult.DifferentPixels}/{compareResult.TotalPixels}"); } } } } File.Delete(finalImageFileName); }
private async Task <byte[]> GenerateDiagram(CommandContext ctx, IEnumerable <IGrouping <long, Slavereports> > groupedReports, TimeSpan timespan) { if (groupedReports.Count() > 5) { throw new ArgumentOutOfRangeException("Maximum allowed number of users in a diagram is 5"); } const int ImageWidth = 1024; const int ImageHeight = 800; const int DiagramSpacingLeft = 90; // Spacing on the left of the Y line const int DiagramSpacingBottom = 120; // Spacing below the X line SKBitmap bmp = new SKBitmap(ImageWidth, ImageHeight); using SKCanvas canvas = new SKCanvas(bmp); // Set black background canvas.Clear(new SKColor(47, 49, 54)); // Create all colors and strokes needed later on SKPaint diagramPaint = new SKPaint() { Color = new SKColor(200, 200, 230), StrokeWidth = 3, IsAntialias = true, }; SKPaint diagramPaintThicc = new SKPaint() { Color = new SKColor(200, 200, 230), StrokeWidth = 6, IsAntialias = true }; SKPaint textPaint = new SKPaint() { Color = new SKColor(200, 200, 230), TextSize = 18f, TextAlign = SKTextAlign.Center, IsAntialias = true, IsEmbeddedBitmapText = true }; SKPaint leftTextPaint = new SKPaint() { Color = new SKColor(200, 200, 230), TextSize = 18f, TextAlign = SKTextAlign.Right, IsAntialias = true, IsEmbeddedBitmapText = true }; // Draw X and Y lines canvas.DrawLine(new SKPoint(DiagramSpacingLeft, 0), new SKPoint(DiagramSpacingLeft, ImageHeight), diagramPaint); canvas.DrawLine(new SKPoint(0, ImageHeight - DiagramSpacingBottom), new SKPoint(ImageWidth, ImageHeight - DiagramSpacingBottom), diagramPaint); const int rows = 8; // max and min time of all reports var maxTime = groupedReports.Max(g => g.Max(r => r.TimeSpan)); var minTime = groupedReports.Min(g => g.Min(r => r.TimeSpan)); var timeDiff = TimeSpan.FromTicks(maxTime - minTime); var individualTime = TimeSpan.FromTicks(maxTime / rows); var individualRowSpacing = Convert.ToInt32((ImageHeight - DiagramSpacingBottom * 1.4f) / rows); var individualColumnSpacing = Convert.ToInt32((ImageWidth - DiagramSpacingLeft * 1.4f) / (timespan.TotalDays + 1)); for (int i = 1; i <= rows; i++) { var y = ImageHeight - DiagramSpacingBottom - individualRowSpacing * i; canvas.DrawLine(new SKPoint(DiagramSpacingLeft - 10, y), new SKPoint(DiagramSpacingLeft + 10, y), diagramPaintThicc); canvas.DrawText((individualTime * i).ToString("hh\\:mm\\:ss"), new SKPoint(DiagramSpacingLeft - 10, y - 10), leftTextPaint); } var xLineHeight = ImageHeight - DiagramSpacingBottom; for (int i = 1; i <= timespan.TotalDays + 2; i++) { var x = DiagramSpacingLeft + individualColumnSpacing * i; canvas.DrawLine(new SKPoint(x, xLineHeight - 10), new SKPoint(x, xLineHeight + 10), diagramPaintThicc); canvas.DrawText((DateTime.Now - timespan + TimeSpan.FromDays(1) + TimeSpan.FromDays(i - 1)).ToString("dd.MM."), new SKPoint(x, xLineHeight + 30), textPaint); } // Create a color for each user SKColor[] userColors = new SKColor[] { new SKColor(36, 123, 160), new SKColor(112, 193, 179), new SKColor(178, 219, 191), new SKColor(243, 255, 189), new SKColor(225, 22, 84) }; for (int i = 0; i < groupedReports.Count(); i++) { var group = groupedReports.ElementAt(i); var color = userColors[i]; var colorBright = new SKColor((byte)(color.Red + 100 > 255 ? 255 : color.Red + 100), (byte)(color.Green + 100 > 255 ? 255 : color.Green + 100), (byte)(color.Blue + 100 > 255 ? 255 : color.Blue + 100)); var paint = new SKPaint() { Color = color, StrokeWidth = 3, TextSize = 18f, TextAlign = SKTextAlign.Center, IsAntialias = true, IsEmbeddedBitmapText = true }; var paintBright = new SKPaint() { Color = colorBright, StrokeWidth = 3, TextSize = 18f, TextAlign = SKTextAlign.Center, IsAntialias = true, IsEmbeddedBitmapText = true }; SKPoint lastCoord = SKPoint.Empty; var user = await ctx.Client.GetUserAsync(Convert.ToUInt64(group.Key)); var spacePerUser = (ImageWidth - DiagramSpacingLeft) / 5; // Get the avatar HttpClient httpClient = new HttpClient(); var userImgResponse = await httpClient.GetAsync(user.AvatarUrl); // Only add the user avatar if it can be downloaded if (userImgResponse.IsSuccessStatusCode) { DiscordMember member = null; try { member = await ctx.Channel.Guild.GetMemberAsync(user.Id); } catch (Exception) { } var antialiasedPaint = new SKPaint() { IsAntialias = true }; textPaint.GetFontMetrics(out SKFontMetrics metrics); var textSpacing = Convert.ToInt32(metrics.XMax + (metrics.XMax / 4)); var x = DiagramSpacingLeft + 5 + spacePerUser * i; var y = ImageHeight - DiagramSpacingBottom + textSpacing; var fullSpace = DiagramSpacingBottom - textSpacing < spacePerUser ? DiagramSpacingBottom : spacePerUser; var halfSpace = fullSpace / 2; var left = halfSpace / 4 * 1; var top = halfSpace / 4 * 1; var size = halfSpace / 4 * 3; var baseBmp = new SKBitmap(spacePerUser, fullSpace - Convert.ToInt32(textSpacing)); var baseCanvas = new SKCanvas(baseBmp); baseCanvas.Clear(color); var userImgBmp = SKBitmap.Decode(await userImgResponse.Content.ReadAsStreamAsync()); var clippedBmp = new SKBitmap(userImgBmp.Width, userImgBmp.Height); SKCanvas userImgCanvas = new SKCanvas(clippedBmp); userImgCanvas.ClipRoundRect(new SKRoundRect(new SKRect(0, 0, userImgBmp.Width, userImgBmp.Height), 100, 100)); userImgCanvas.DrawBitmap(userImgBmp, 0, 0, antialiasedPaint); userImgCanvas.Flush(); baseCanvas.DrawBitmap(clippedBmp, new SKRect(left, top, left + size, top + size), antialiasedPaint); SKPaint namePaint = new SKPaint() { Color = new SKColor(47, 49, 54), TextAlign = SKTextAlign.Left, TextSize = 18, IsAntialias = true, IsEmbeddedBitmapText = true, }; DrawTextArea(baseCanvas, namePaint, left * 2 + size, top * 2, spacePerUser - left * 2 + size, 15, member?.Nickname ?? user.Username); canvas.DrawBitmap(baseBmp, new SKPoint(x, y), antialiasedPaint); } foreach (var report in group) { var minDate = (DateTime.Now - timespan).Date; var maxDate = (DateTime.Now + TimeSpan.FromDays(1)).Date; var totalSpace = individualColumnSpacing * (timespan.TotalDays + 1); var percentPointPerTick = (float)totalSpace / (maxDate - minDate).Ticks; var x = DiagramSpacingLeft + (percentPointPerTick * (report.TimeOfReport - minDate).Ticks); //Subtract the time of the report from the mindate, to get the time relative from the beginning of the graph. multiply by percentagepoint of a tick on the graph. add spacing, var y = ImageHeight - DiagramSpacingBottom - ((ImageHeight - (DiagramSpacingBottom * 1.4f)) / Convert.ToSingle(maxTime) * report.TimeSpan); var coord = new SKPoint(x, y); canvas.DrawCircle(coord, 8, paint); canvas.DrawText(TimeSpan.FromTicks(report.TimeSpan).ToString(), new SKPoint(coord.X, coord.Y - 10), paintBright); //canvas.DrawText(report.TimeOfReport.ToString(), new SKPoint(coord.X, coord.Y + 15), paintBright); if (lastCoord != SKPoint.Empty) { canvas.DrawLine(lastCoord, coord, paint); } lastCoord = coord; } } using var ms = new MemoryStream(); using SKManagedWStream skStream = new SKManagedWStream(ms); if (SKPixmap.Encode(skStream, bmp, SKEncodedImageFormat.Png, 100)) { return(ms.ToArray()); } return(Array.Empty <byte>()); }