private SKBitmap BuildSquareCollageBitmap(IReadOnlyList <string> paths, int width, int height) { var bitmap = new SKBitmap(width, height); var imageIndex = 0; var cellWidth = width / 2; var cellHeight = height / 2; using var canvas = new SKCanvas(bitmap); for (var x = 0; x < 2; x++) { for (var y = 0; y < 2; y++) { using var currentBitmap = SkiaHelper.GetNextValidImage(_skiaEncoder, paths, imageIndex, out int newIndex); imageIndex = newIndex; if (currentBitmap == null) { continue; } // Scale image. The FromBitmap creates a copy var imageInfo = new SKImageInfo(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType, currentBitmap.ColorSpace); using var resizedBitmap = SKBitmap.FromImage(SkiaEncoder.ResizeImage(currentBitmap, imageInfo)); // draw this image into the strip at the next position var xPos = x * cellWidth; var yPos = y * cellHeight; canvas.DrawBitmap(resizedBitmap, xPos, yPos); } } return(bitmap); }
public void GpuTextureSurfaceCanBeRead() { DrawGpuTexture((surface, texture) => { var canvas = surface.Canvas; canvas.Clear(SKColors.Red); canvas.Flush(); using (var image = surface.Snapshot()) { Assert.True(image.IsTextureBacked); using (var raster = image.ToRasterImage()) { Assert.False(raster.IsTextureBacked); using (var bmp = SKBitmap.FromImage(raster)) { Assert.Equal(SKColors.Red, bmp.GetPixel(0, 0)); } } } }); }
public static Bitmap ToBitmap(this SKImage skiaImage) { return(new Bitmap() { nativeSkBitmap = SKBitmap.FromImage(skiaImage) }); }
public WindowDataModel(Process process, IColorQuantizerService quantizerService) { Process = process; ProcessName = process.ProcessName; // Accessing MainModule requires admin privileges, this way does not ProgramLocation = process.GetProcessFilename(); // Get Icon colors if (!File.Exists(ProgramLocation)) { return; } using MemoryStream stream = new(); Icon.ExtractAssociatedIcon(ProgramLocation)?.Save(stream); stream.Seek(0, SeekOrigin.Begin); using SKBitmap bitmap = SKBitmap.FromImage(SKImage.FromEncodedData(stream)); stream.Close(); if (bitmap == null) { return; } SKColor[] colors = quantizerService.Quantize(bitmap.Pixels, 256); Colors = quantizerService.FindAllColorVariations(colors, true); }
public ProcessImage Encode(SKImage img, ProcessImageType toType, bool flipHorizontal, bool flipVertical) { if (flipHorizontal || flipVertical) { using SKBitmap bmp = new SKBitmap(img.Width, img.Height); using SKCanvas surface = new SKCanvas(bmp); surface.Scale(flipHorizontal ? -1 : 1, flipVertical ? -1 : 1, flipHorizontal ? img.Width / 2f : 0, flipVertical ? img.Height / 2f : 0); surface.DrawImage(img, 0, 0); img = SKImage.FromBitmap(bmp); } if (toType == ProcessImageType.JPEG) { return(new ProcessImage { Load = img.Encode(SKEncodedImageFormat.Jpeg, 95).ToArray(), Type = toType, Width = img.Width, Height = img.Height }); } if (toType == ProcessImageType.PNG) { return(new ProcessImage { Load = img.Encode(SKEncodedImageFormat.Png, 95).ToArray(), Type = toType, Width = img.Width, Height = img.Height }); } if (toType == ProcessImageType.RGBA8) { SKBitmap bmp = SKBitmap.FromImage(img); return(new ProcessImage { Load = bmp.Bytes, Height = bmp.Height, Type = toType, Width = bmp.Width }); } throw new FormatException("Format conversion not implemented"); }
SKBitmap RenderThumbnailInternal(SKBitmap bitmap) { SKBitmap resizedBitmap = null; if (base.CalculateNewSize(new Int2(bitmap.Width, bitmap.Height), this.DesiredSize, out Int2 size, out IntRect cropArea)) { // generate new cropped bitmap using (var surface = SKSurface.Create(new SKImageInfo(size.X, size.Y, SKColorType.Bgra8888))) { // the the canvas and properties var canvas = surface.Canvas; // make sure the canvas is blank canvas.Clear(SKColors.White); canvas.DrawBitmap( bitmap, new SKRect(cropArea.Left, cropArea.Top, cropArea.Width, cropArea.Height), new SKRect(0, 0, size.X, size.Y), new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true } ); using (var image = surface.Snapshot()) { resizedBitmap = SKBitmap.FromImage(image); } } }
public static bool CompareBitmaps(Stream?bitmapStream1, Stream?bitmapStream2, int allowedColorDistance = 0, double proportionCorrect = 1) { // The bitmaps in WPF can slightly differ from test to test. No idea why. So introduced proportion correct. long trueCount = 0; long falseCount = 0; if (bitmapStream1 == null && bitmapStream2 == null) { return(true); } if (bitmapStream1 == null || bitmapStream2 == null) { return(false); } bitmapStream1.Position = 0; bitmapStream2.Position = 0; using var skData1 = SKData.Create(bitmapStream1); var bitmap1 = SKBitmap.FromImage(SKImage.FromEncodedData(skData1)); using var skData2 = SKData.Create(bitmapStream2); var bitmap2 = SKBitmap.FromImage(SKImage.FromEncodedData(skData2)); if (bitmap1.Width != bitmap2.Width || bitmap1.Height != bitmap2.Height) { return(false); } for (var x = 0; x < bitmap1.Width; x++) { for (var y = 0; y < bitmap1.Height; y++) { var color1 = bitmap1.GetPixel(x, y); var color2 = bitmap2.GetPixel(x, y); if (color1 == color2) { trueCount++; } else { if (CompareColors(color1, color2, allowedColorDistance)) { trueCount++; } else { falseCount++; } } } } var proportion = (double)(trueCount) / (trueCount + falseCount); return(proportionCorrect <= proportion); }
/// <summary> /// Transform the images ready for download, optionally adding a watermark. /// </summary> /// <param name="input"></param> /// <param name="output"></param> /// <param name="waterMarkText"></param> public void TransformDownloadImageSync(string input, Stream output, IExportSettings config) { using SKImage img = SKImage.FromEncodedData(input); using var bitmap = SKBitmap.FromImage(img); float maxSize = config.MaxImageSize; var resizeFactor = 1f; if (bitmap.Width > maxSize) { resizeFactor = maxSize / bitmap.Width; } else if (bitmap.Height > maxSize) { resizeFactor = maxSize / bitmap.Height; } var targetWidth = (int)Math.Round(bitmap.Width * resizeFactor); var targetHeight = (int)Math.Round(bitmap.Height * resizeFactor); // First create a bitmap the right size. using var toBitmap = new SKBitmap(targetWidth, targetHeight, bitmap.ColorType, bitmap.AlphaType); using var canvas = new SKCanvas(toBitmap); // Draw a bitmap rescaled canvas.SetMatrix(SKMatrix.CreateScale(resizeFactor, resizeFactor)); canvas.DrawBitmap(bitmap, 0, 0); canvas.ResetMatrix(); if (!string.IsNullOrEmpty(config.WatermarkText)) { using var font = SKTypeface.FromFamilyName("Arial"); using var brush = new SKPaint { Typeface = font, TextSize = 64.0f, IsAntialias = true, Color = new SKColor(255, 255, 255, 255) }; var textWidth = brush.MeasureText(config.WatermarkText); var textTargetWidth = targetWidth / 6f; var fontScale = textTargetWidth / textWidth; brush.TextSize *= fontScale; // Offset by text width + 10% var rightOffSet = (textTargetWidth * 1.1f); canvas.DrawText(config.WatermarkText, targetWidth - rightOffSet, targetHeight - brush.TextSize, brush); } canvas.Flush(); using var image = SKImage.FromBitmap(toBitmap); using var data = image.Encode(SKEncodedImageFormat.Jpeg, 90); data.SaveTo(output); }
private SKBitmap Scale(SKBitmap input, int width, int height) { var info = new SKImageInfo(width, height); var newImg = SKImage.Create(info); input.ScalePixels(newImg.PeekPixels(), SKFilterQuality.Medium); return(SKBitmap.FromImage(newImg)); }
// Draw on canvas void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; // Initialize canvas if resetcanvas is true if (resetcanvas) { // Delete paths while (paths.Count > 0) { paths.RemoveAt(0); } // Clear canvas in white canvas.Clear(SKColors.White); // Reset flag for erasing canvas resetcanvas = false; } // Draw all paths (if resetcanvas is not set) else { // Define paint brush var touchPathStroke = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Stroke, Color = SKColors.Black, StrokeWidth = 0.05f * Math.Min(info.Width, info.Height), StrokeCap = SKStrokeCap.Round }; // Draw paths (currently "in drawing" and finalized) foreach (var touchPath in temporaryPaths) { canvas.DrawPath(touchPath.Value, touchPathStroke); } foreach (var touchPath in paths) { canvas.DrawPath(touchPath, touchPathStroke); } } // Save canvas to bitmap in page "CameraTestPage" // This coding is not elegant / robust but it works if (savetobitmap) { Application app = Application.Current; CameraTestPage page = app.MainPage.Navigation.NavigationStack[1] as CameraTestPage; var image = surface.Snapshot(); page.bitmap = SKBitmap.FromImage(image); savetobitmap = false; } }
public static Image FromStream(Stream ms) { var ans = new Bitmap() { nativeSkBitmap = SKBitmap.FromImage(SKImage.FromEncodedData(ms)) }; return(ans); }
public static void mergeTiles(string folderPath) { if (folderPath.Last() == '/' || folderPath.Last() == '\\') { folderPath = folderPath.Remove(folderPath.Length - 1); } Dictionary <string, SKImage> images = new Dictionary <string, SKImage>(); int maxNumOfLevels = 3; for (int level = maxNumOfLevels; level > 0; --level) { int numOfTiles = Convert.ToInt32(Math.Pow(4, level - 1)); int tilesToASide = Convert.ToInt32(Math.Sqrt(numOfTiles)); for (int globaly = 0; globaly < tilesToASide; ++globaly) { for (int globalx = 0; globalx < tilesToASide; ++globalx) { var tempSurface = SKSurface.Create(new SKImageInfo(512, 512)); var canvas = tempSurface.Canvas; canvas.Clear(SKColors.Transparent); for (int tiley = 0; tiley < 2; ++tiley) { for (int tilex = 0; tilex < 2; ++tilex) { int imgx = (globalx * 2 + tilex); int imgy = (globaly * 2 + tiley); string tilePath = $"{folderPath}/aqlatestL{level}T{(globalx * 2 + tilex).ToString("D2")}{(globaly * 2 + tiley).ToString("D2")}.png"; string tileKey = $"L{level}T{(globalx * 2 + tilex).ToString("D2")}{(globaly * 2 + tiley).ToString("D2")}"; if (images.ContainsKey(tileKey)) { SKBitmap tile = SKBitmap.FromImage(images[tileKey]); canvas.DrawBitmap(tile, SKRect.Create(tilex * 256, tiley * 256, tile.Width, tile.Height)); } else if (File.Exists(tilePath)) { SKBitmap tile = SKBitmap.Decode(File.OpenRead(tilePath)); canvas.DrawBitmap(tile, SKRect.Create(tilex * 256, tiley * 256, tile.Width, tile.Height)); } } } SKBitmap bigTile = SKBitmap.FromImage(tempSurface.Snapshot()); SKBitmap littleTile = SKBitmap.FromImage(SKImage.Create(new SKImageInfo(256, 256))); bigTile.ScalePixels(littleTile, SKFilterQuality.High); SKImage outTile = SKImage.FromBitmap(littleTile); images.Add($"L{level - 1}T{globalx.ToString("D2")}{globaly.ToString("D2")}", outTile); } } } foreach (KeyValuePair <string, SKImage> file in images) { var data = file.Value.Encode(); var stream = File.OpenWrite($"{folderPath}/aqlatest{file.Key}.png"); data.SaveTo(stream); } }
/// <summary> /// Get the Oled Bytes needed to render. Does not keep aspect ratio, consider using GetOledBytesMaxSize(x,y); /// </summary> /// <param name="newWidth"></param> /// <param name="newHeight"></param> /// <returns></returns> public OledImageData GetOledBytes(int newWidth, int newHeight) { var skImageInfo = new SKImageInfo(newWidth, newHeight, SKColorType.Gray8, SKAlphaType.Unpremul); using var bmp = SKBitmap.FromImage(_image); using var bmp1 = bmp.Resize(skImageInfo, SKFilterQuality.High); return(new OledImageData(newWidth, newHeight, bmp1.GetPixelSpan().ToArray())); }
public static SKImage CopyBitmapRegion(SKBitmap bmp, int width, int height, SKRectI srcRegion) { using (var output = new SKBitmap(width, height)) { bmp.ExtractSubset(output, srcRegion); var img = SKImage.FromBitmap(output); return(SKImage.FromBitmap(SKBitmap.FromImage(img))); } }
public override Image Scale(float scale) { using (var oldBitmap = SKBitmap.FromImage(SKImage)) { SKImageInfo resizeInfo = new SKImageInfo((int)(SKImage.Width * scale), (int)(SKImage.Height * scale)); using (var resizedSKBitmap = oldBitmap.Resize(resizeInfo, SKFilterQuality.High)) { return(new SkiaImage(SKImage.FromBitmap(resizedSKBitmap))); } } }
// Convert bitmap to grayscale and apply contrast to emphasize lines // For conversion SKColorFilter is used // However, SKColorFilter is usually set in SKPaint object and applied to canvas when drawn // To apply it to the bitmap, we have to convert bitmap to image because it's possible to apply filters to images SKBitmap ConvertBitmapToGray(SKBitmap bitmap, float contr = contrast) { SKImage image = SKImage.FromBitmap(bitmap); SKImageFilter imagefilter = SKImageFilter.CreateColorFilter(SKColorFilter.CreateHighContrast(true, SKHighContrastConfigInvertStyle.NoInvert, contrast)); SKRectI rectout = new SKRectI(); SKPoint pointout = new SKPoint(); image = image.ApplyImageFilter(imagefilter, new SKRectI(0, 0, image.Width, image.Height), new SKRectI(0, 0, image.Width, image.Height), out rectout, out pointout); return(SKBitmap.FromImage(image)); }
private async Task <byte[]> CreateMapImageAsync( int width, int height, Models.Bounds boundingBox, string mediaType, bool isTransparent, uint backgroundColor, IList <string> layerNames) { var imageInfo = new SKImageInfo( width: width, height: height, colorType: SKColorType.Rgba8888, alphaType: SKAlphaType.Premul); using var surface = SKSurface.Create(imageInfo); using var canvas = surface.Canvas; canvas.Clear(new SKColor(backgroundColor)); foreach (var layerName in layerNames) { if (this.tileSourceFabric.Contains(layerName)) { await WmsHelper.DrawLayerAsync( // TODO: ? pass required format to avoid conversions this.tileSourceFabric.Get(layerName), width, height, boundingBox, canvas, isTransparent, backgroundColor); } } using SKImage image = surface.Snapshot(); if (String.Compare(mediaType, MediaTypeNames.Image.Tiff, StringComparison.OrdinalIgnoreCase) == 0) { using var bitmap = SKBitmap.FromImage(image); // TODO: improve performance of pixels processing, maybe using unsafe/pointers var pixels = bitmap.Pixels.SelectMany(p => new byte[] { p.Red, p.Green, p.Blue, p.Alpha }).ToArray(); var tiff = ImageHelper.CreateTiffImage(pixels, image.Width, image.Height); return(tiff); } else { var imageFormat = U.ImageHelper.SKEncodedImageFormatFromMediaType(mediaType); using SKData data = image.Encode(imageFormat, 90); // TODO: ? quality parameter return(data.ToArray()); } }
/// <summary> /// Loads an image from a disk file, decoding for the optimal required /// size so that we don't load the entire image for a smaller target, /// and auto-orienting the bitmap according to the codec origin. /// </summary> /// <param name="source"></param> /// <param name="desiredWidth"></param> /// <returns></returns> private SKBitmap SlowLoadOrientedBitmap(FileInfo source, int desiredWidth) { Stopwatch load = new Stopwatch("SkiaSharpLoad"); using SKImage img = SKImage.FromEncodedData(source.FullName); var bmp = SKBitmap.FromImage(img); Logging.LogTrace($"Loaded {source.Name} - loaded size = W: {bmp.Width}, H: {bmp.Height}"); load.Stop(); return(bmp); }
private static string CreateInputFile() { var inputPath = GetTempPath(); using (var stream = File.OpenWrite(inputPath)) { SKBitmap.FromImage(SKImage.Create(new SKImageInfo(100, 100))) .PeekPixels() .Encode(SKPngEncoderOptions.Default) .SaveTo(stream); } return(inputPath); }
public GlobalCache(PakIndex index) { Index = index; VBucksIcon = index.GetPackage("/FortniteGame/Content/UI/Foundation/Shell/Textures/T-Icon-VBucks-L").GetExport <Texture2D>().Image; var img = index.GetPackage("/FortniteGame/Content/VisualThreatManager/StormVisuals/Test/SpawnParticles/Streamers/LowResBlurredNoise").GetExport <Texture2D>().Image; // don't dispose objects given by exports using (var b = SKBitmap.FromImage(img)) using (var b2 = new SKBitmap(new SKImageInfo(b.Width * 2, b.Height * 2), SKBitmapAllocFlags.ZeroPixels)) { using (var c = new SKCanvas(b2)) using (var s = SKShader.CreateColorFilter(SKShader.CreateBitmap(b, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat), SKColorFilter.CreateLighting(new SKColor(160, 160, 160), new SKColor(15, 15, 15)))) { c.DrawRect(0, 0, b2.Width, b2.Height, new SKPaint { Shader = s }); } using (var borderNoiseBig = b2.Resize(new SKImageInfo(b2.Width * 16, b2.Height * 16), SKFilterQuality.Medium)) using (var borderNoise = new SKBitmap(b.Width * 16, b.Width * 16)) { borderNoiseBig.ExtractSubset(borderNoise, new SKRectI(b2.Width * 4, b2.Width * 4, b2.Width * 12, b2.Width * 12)); BaseBorderShader = SKShader.CreateBitmap(borderNoise, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat); } } NameTypeface = SKTypeface.FromStream(index.GetFile("/FortniteGame/Content/UI/Foundation/Fonts/BurbankBigCondensed-Black.ufont").AsStream()); ShortDescriptionTypeface = SKTypeface.FromStream(index.GetFile("/FortniteGame/Content/UI/Foundation/Fonts/NotoSans-Regular.ufont").AsStream()); PriceTypeface = SKTypeface.FromStream(index.GetFile("/FortniteGame/Content/UI/Foundation/Fonts/NotoSans-Bold.ufont").AsStream()); CategoryTypeface = SKTypeface.FromStream(index.GetFile("/FortniteGame/Content/UI/Foundation/Fonts/NotoSans-Bold.ufont").AsStream()); ImagePaint = new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High }; { var types = EnumHelper <DrawType> .Values; SectionCaches = new SectionCache[types.Length]; for (int i = 0; i < types.Length; i++) { SectionCaches[i] = new SectionCache(types[i], this); } } { RarityColors = new ColorPalette[] { new ColorPalette(this, default, new SKColor(150, 150, 150), new SKColor(50, 53, 58), new SKColor(212, 212, 212), new SKColor(249, 249, 249)), // COMMON
public static Image FromStream(Stream ms) { MemoryStream ms2 = new MemoryStream(); ms.CopyTo(ms2); ms2.Position = 0; var skimage = SKImage.FromEncodedData(ms2); var skbitmap = SKBitmap.FromImage(skimage); var ans = new Bitmap() { nativeSkBitmap = skbitmap }; return(ans); }
private Icon(SerializationInfo info, StreamingContext context) { iconData = (byte[])info.GetValue("IconData", typeof(byte[])); iconSize = (Size)info.GetValue("IconSize", typeof(Size)); if (iconSize.IsEmpty) { //Initialize(0, 0); nativeSkBitmap = new SKBitmap(); } else { nativeSkBitmap = SKBitmap.FromImage(SKImage.FromEncodedData(new MemoryStream(iconData))); iconSize = new Size(nativeSkBitmap.Width, nativeSkBitmap.Height); } }
/// <summary> /// Writes all data to a new <see cref="SKBitmap"/> instance /// </summary> /// <returns></returns> /// <exception cref="Exception">Invalid length!</exception> public static SKBitmap ToSKBitmap(this ARGBImageData imageData) { SKImageInfo imgInfo = new SKImageInfo(imageData.Width, imageData.Height, SKColorType.Rgba8888, SKAlphaType.Unpremul); var bitmap = SKBitmap.FromImage(SkiaSharp.SKImage.Create(imgInfo)); IntPtr len; IntPtr ptr = bitmap.GetPixels(out len); int byteLen = imageData.Data.Length * 4; if (len.ToInt32() != byteLen) { throw new Exception("Invalid length!"); } Marshal.Copy(imageData.Data, 0, ptr, imageData.Data.Length); return(bitmap); }
public void DrawText(float x = 0, float y = 0, string text = "", int size = 24, string font = "Arial", string color = "#ff000000") { using (var surface = SKSurface.Create(new SKImageInfo(Context.Image.Width, Context.Image.Height))) using (var canvas = surface.Canvas) using (var paint = new SKPaint() { TextSize = size, IsAntialias = true, Color = SKColor.Parse(color) }) { canvas.DrawBitmap(Context.Image, 0, 0); canvas.DrawText(text, Context.Image.Width * x, Context.Image.Height * y, new SKFont(SKTypeface.FromFamilyName(font)), paint); canvas.Flush(); Context.Image = SKBitmap.FromImage(surface.Snapshot()); } }
private SKBitmap RemoveTransparency(SKImage orig) { var original = SKBitmap.FromImage(orig); // create a new bitmap with the same dimensions // also avoids the first copy if the color type is index8 var copy = new SKBitmap(original.Width, original.Height); using var canvas = new SKCanvas(copy); // clear the bitmap with the desired color for transparency canvas.Clear(SKColors.White); // draw the bitmap on top canvas.DrawBitmap(original, 0, 0); return(copy); }
private string ChekeResult() { if (skimage == null) { return(null); } SKBitmap bitmap = SKBitmap.FromImage(skimage); var scaledBitmap = bitmap.Resize(new SKImageInfo(400, 400), SKBitmapResizeMethod.Triangle); skimage = SKImage.FromBitmap(scaledBitmap); bitmap = SKBitmap.FromImage(skimage); SKData pngImage = skimage.Encode(); var byteArray = pngImage.ToArray(); Stream stream = new MemoryStream(byteArray); ImageDim.Source = ImageSource.FromStream(() => { return(stream); }); SKColor[] arrColors = bitmap.Pixels; List <bool> boolImage = new List <bool>(); foreach (var item in arrColors) { boolImage.Add(item.ToFormsColor() == Color.Black); } string answer = "no"; double resultamountWeights = double.MinValue; foreach (var item in answers) { double amountWeights = 0.1; for (int i = 0; i < item.Weights.Count; i++) { double valueImage = boolImage[i] ? 1 : 0; amountWeights += valueImage * item.Weights[i]; } if (resultamountWeights < amountWeights) { resultamountWeights = amountWeights; answer = item.Name; } } return(answer); }
public void Blur(int radius) { using (var surface = SKSurface.Create(new SKImageInfo(Context.Image.Width, Context.Image.Height))) using (var canvas = surface.Canvas) using (var paint = new SKPaint()) { paint.ImageFilter = SKImageFilter.CreateBlur(radius, radius); SKRect rect = new SKRect(0, 0, Context.Image.Width, Context.Image.Height); rect.Inflate(10, 10); //removes black border canvas.DrawBitmap(Context.Image, rect, paint); canvas.Flush(); // save Context.Image = SKBitmap.FromImage(surface.Snapshot()); } }
/// <summary> /// Stacks the list of images vertically, stretching them to all have the same width /// Note that we stack them bottom-up (by reversing image order), because uv coordinate system has v=0 starting at the bottom /// </summary> /// <param name="images">The images to stack</param> /// <returns>The stacked images</returns> public static SKImage StackImages(List <SKImage> images) { images.Reverse(); SKBitmap newBitmap = new SKBitmap(images.Max(i => i.Width), images.Select(i => i.Height).Aggregate((h1, h2) => h1 + h2)); using (SKCanvas canvas = new SKCanvas(newBitmap)) { canvas.Clear(); var h = 0; foreach (var img in images) { var bitmap = SKBitmap.FromImage(img).Resize(new SKSizeI(newBitmap.Width, img.Height), SKFilterQuality.High); canvas.DrawBitmap(bitmap, new SKPoint(0, h)); h += img.Height; } } return(SKImage.FromBitmap(newBitmap)); }
public static PixelEnum[][] GetPixelsFromSKImage(SKImage Source, Func <SKColor, PixelEnum> PixelMapRoutine) { PixelEnum[][] Result = new PixelEnum[Source.Height][]; using (SKBitmap WorkMap = SKBitmap.FromImage(Source)) { for (int y = 0; y < Source.Height; y++) { Result[y] = new PixelEnum[Source.Width]; for (int x = 0; x < Source.Width; x++) { SKColor currPixel = WorkMap.GetPixel(x, y); PixelEnum result = PixelMapRoutine(currPixel); Result[y][x] = result; } } } return(Result); }
public void Rotate(float angle) { int w; int h; if (angle < 90) { w = (int)(Math.Abs(Context.Image.Width * Math.Cos(angle)) + Math.Abs(Context.Image.Height * Math.Sin(angle))); h = (int)(Math.Abs(Context.Image.Width * Math.Sin(angle)) + Math.Abs(Context.Image.Height * Math.Cos(angle))); } else if (angle == 90) { w = Context.Image.Height; h = Context.Image.Width; } else if (angle == 180) { w = Context.Image.Width; h = Context.Image.Height; } else if (angle == 270) { w = Context.Image.Height; h = Context.Image.Width; } else { throw new Exception(); } using (var surface = SKSurface.Create(new SKImageInfo(w, h))) using (var canvas = surface.Canvas) { canvas.Translate(Math.Abs(w - Context.Image.Width) / 2, Math.Abs(h - Context.Image.Height) / 2); canvas.RotateDegrees(angle, Context.Image.Width / 2, Context.Image.Height / 2); canvas.DrawBitmap(Context.Image, 0, 0); canvas.Flush(); // save Context.Image = SKBitmap.FromImage(surface.Snapshot()); } }