/// <summary> /// This class takes care of the image processing. It implements a method for resizing images and another for /// adding watermarks /// /// It uses the library SkiaSharp /// /// The caller is agnostic of the library used, it passes and receives images as raw byte arrays. The class /// could be refactored to use a different library without affecting the rest of the code. /// /// Improvements could be made, like being able to specify the color or the location of the watermark /// </summary> /// <param name="image"></param> /// <param name="maxWidth"></param> /// <param name="maxHeight"></param> /// <param name="quality"></param> /// <returns></returns> public DrinkImage Resize(DrinkImage image, int maxWidth, int maxHeight, SKFilterQuality quality = SKFilterQuality.Medium) { using MemoryStream ms = new MemoryStream(image.Bytes); using SKBitmap sourceBitmap = SKBitmap.Decode(ms); // Calculate height and width. We have to decide what to do when one of the parameters was not passed // and was defaulted to 0, or when the parameters passed have a different horizontal/vertical ratio // We want to create the smaller file that respects at least one of the 2 sizes provided and that has // the same horiz to vertical ratio as the image var horiz2vertRatio = sourceBitmap.Width / (double)sourceBitmap.Height; maxWidth = maxWidth == 0 ? sourceBitmap.Width : maxWidth; maxHeight = maxHeight == 0 ? sourceBitmap.Height : maxHeight; var newHorizSize = (int)Math.Round(Math.Min(maxWidth, horiz2vertRatio * maxHeight)); var newVertSize = (int)Math.Round(Math.Min(maxHeight, maxWidth / horiz2vertRatio)); using SKBitmap scaledBitmap = sourceBitmap.Resize(new SKImageInfo(newHorizSize, newVertSize), quality); using SKImage scaledImage = SKImage.FromBitmap(scaledBitmap); using SKData data = scaledImage.Encode(); return(new DrinkImage { Bytes = data.ToArray(), HorizontalSize = newHorizSize, VerticalSize = newVertSize, Watermark = image.Watermark, ImageName = image.ImageName }); }
public bool ScalePixels(SKPixmap dst, SKFilterQuality quality, SKImageCachingHint cachingHint) { if (dst == null) { throw new ArgumentNullException(nameof(dst)); } return(SkiaApi.sk_image_scale_pixels(Handle, dst.Handle, quality, cachingHint)); }
public bool ScalePixels(SKPixmap destination, SKFilterQuality quality) { if (destination == null) { throw new ArgumentNullException(nameof(destination)); } return(SkiaApi.sk_pixmap_scale_pixels(Handle, destination.Handle, quality)); }
public SKBitmap Resize (SKImageInfo info, SKFilterQuality quality) { var dst = new SKBitmap (info); if (ScalePixels (dst, quality)) { return dst; } else { dst.Dispose (); return null; } }
public bool ScalePixels (SKPixmap destination, SKFilterQuality quality) { if (destination == null) { throw new ArgumentNullException (nameof (destination)); } using (var srcPix = PeekPixels ()) { return srcPix.ScalePixels (destination, quality); } }
public bool ScalePixels (SKBitmap destination, SKFilterQuality quality) { if (destination == null) { throw new ArgumentNullException (nameof (destination)); } using (var dstPix = destination.PeekPixels ()) { return ScalePixels (dstPix, quality); } }
public SKPixmap ScalePixels(SKFilterQuality quality, SKImageCachingHint cachingHint) { var pixmap = new SKPixmap(); if (!ScalePixels(pixmap, quality, cachingHint)) { pixmap.Dispose(); pixmap = null; } return(pixmap); }
public MainPage() { InitializeComponent(); _currentMatrix = SKMatrix.MakeIdentity(); _images = new List <MyImage>(); _quality = SKFilterQuality.None; var pinch = new PinchGestureRecognizer(); pinch.PinchUpdated += Pinch_PinchUpdated; SkiaView.GestureRecognizers.Add(pinch); SkiaView.EnableTouchEvents = true; SkiaView.Touch += SkiaView_Touch; var assembly = typeof(MainPage).GetTypeInfo().Assembly; _buffer = new List <byte[]>(); for (int i = 0; i < 24; i++) { var names = assembly.GetManifestResourceNames(); using (Stream s = assembly.GetManifestResourceStream("SkiaXFPlayground.img" + i + ".jpg")) { if (s != null) { long length = s.Length; var b = new byte[length]; s.Read(b, 0, (int)length); _buffer.Add(b); } } LogLabel.Text = "Loading image: " + i; } LogLabel.Text = "buffering finished"; var x = 0; var y = 0; var im = SKImage.FromEncodedData(_buffer.ElementAt(0)); var img = new MyImage() { Image = im }; img.Destination = new SKRect(x, y, x + imagesize, y + imagesize); LogLabel.Text = "image added "; LogLabel.Text = "decoding finished " + _images.Count; }
public static (byte[] FileContents, int Height, int Width) Resize(byte[] fileContents, int maxWidth, int maxHeight, SKFilterQuality quality = SKFilterQuality.Medium) { using MemoryStream ms = new MemoryStream(fileContents); using SKBitmap sourceBitmap = SKBitmap.Decode(ms); int height = Math.Min(maxHeight, sourceBitmap.Height); int width = Math.Min(maxWidth, sourceBitmap.Width); using SKBitmap scaledBitmap = sourceBitmap.Resize(new SKImageInfo(width, height), quality); using SKImage scaledImage = SKImage.FromBitmap(scaledBitmap); using SKData data = scaledImage.Encode(); return(data.ToArray(), height, width); }
public static AVMI.BitmapInterpolationMode ToBitmapInterpolationMode(this SKFilterQuality filterQuality) { switch (filterQuality) { default: case SKFilterQuality.None: return(AVMI.BitmapInterpolationMode.Default); case SKFilterQuality.Low: return(AVMI.BitmapInterpolationMode.LowQuality); case SKFilterQuality.Medium: return(AVMI.BitmapInterpolationMode.MediumQuality); case SKFilterQuality.High: return(AVMI.BitmapInterpolationMode.HighQuality); } }
public async Task <SKImage> GetScaledDownImage(SKBitmap bitmap, SKImageInfo imageInfo, SKFilterQuality quality, int maxDimensionLength) { int width = imageInfo.Width, height = imageInfo.Height; float scale; if (width >= height) { scale = (float)maxDimensionLength / width; } else { scale = (float)maxDimensionLength / height; } var newSize = new SKSizeI((int)(scale * width), (int)(scale * height)); return(await Task.Run(() => SKImage.FromBitmap(bitmap.Resize(newSize, quality)))); }
void Quality_SelectedIndexChanged(System.Object sender, System.EventArgs e) { switch (QualityPicker.SelectedIndex) { case 0: _quality = SKFilterQuality.None; break; case 1: _quality = SKFilterQuality.Low; break; case 2: _quality = SKFilterQuality.Medium; break; case 3: _quality = SKFilterQuality.High; break; } SkiaView.InvalidateSurface(); }
public SKPaint() { Style = SKPaintStyle.Fill; IsAntialias = false; StrokeWidth = 0; StrokeCap = SKStrokeCap.Butt; StrokeJoin = SKStrokeJoin.Miter; StrokeMiter = 4; Typeface = null; TextSize = 12; TextAlign = SKTextAlign.Left; LcdRenderText = false; SubpixelText = false; TextEncoding = SKTextEncoding.Utf8; Color = new SKColor(0x00, 0x00, 0x00, 0xFF); Shader = null; ColorFilter = null; ImageFilter = null; PathEffect = null; BlendMode = SKBlendMode.SrcOver; FilterQuality = SKFilterQuality.None; }
private byte[] Process(byte[] src, int width, string overlay, SKFilterQuality quality = SKFilterQuality.High) { try { using var ms = new MemoryStream(src); using var sourceBitmap = SKBitmap.Decode(ms); var aspectRatio = (float)sourceBitmap.Height / sourceBitmap.Width; var height = (int)Math.Round(width * aspectRatio); using var scaledBitmap = sourceBitmap.Resize(new SKImageInfo(width, height), quality); if (!string.IsNullOrWhiteSpace(overlay)) { var canvas = new SKCanvas(scaledBitmap); var font = SKTypeface.FromFamilyName("Arial"); var brush = new SKPaint { Typeface = font, TextSize = 64.0f, IsAntialias = true, Color = new SKColor(255, 255, 255, 255) }; canvas.DrawText(overlay, 0, scaledBitmap.Height, brush); canvas.Flush(); } using var scaledImage = SKImage.FromBitmap(scaledBitmap); using var data = scaledImage.Encode(); return(data.ToArray()); } catch { return(src); } }
public bool ScalePixels(SKPixmap dst, SKFilterQuality quality) { return(ScalePixels(dst, quality, SKImageCachingHint.Allow)); }
public static SKImageFilter CreatePictureForLocalspace(SKPicture picture, SKRect cropRect, SKFilterQuality filterQuality) { if (picture == null) { throw new ArgumentNullException(nameof(picture)); } return(GetObject <SKImageFilter>(SkiaApi.sk_imagefilter_new_picture_for_localspace(picture.Handle, ref cropRect, filterQuality))); }
public extern static sk_imagefilter_t sk_imagefilter_new_matrix(ref SKMatrix matrix, SKFilterQuality quality, sk_imagefilter_t input /*NULL*/);
public static SKImageFilter CreateMatrix(SKMatrix matrix, SKFilterQuality quality, SKImageFilter input = null) { return GetObject<SKImageFilter>(SkiaApi.sk_imagefilter_new_matrix(ref matrix, quality, input == null ? IntPtr.Zero : input.Handle)); }
public static SKImageFilter CreatePictureForLocalspace(SKPicture picture, SKRect cropRect, SKFilterQuality filterQuality) { if (picture == null) throw new ArgumentNullException(nameof(picture)); return GetObject<SKImageFilter>(SkiaApi.sk_imagefilter_new_picture_for_localspace(picture.Handle, ref cropRect, filterQuality)); }
public static SKImageFilter CreateImage(SKImage image, SKRect src, SKRect dst, SKFilterQuality filterQuality) { if (image == null) { throw new ArgumentNullException(nameof(image)); } return(GetObject <SKImageFilter>(SkiaApi.sk_imagefilter_new_image_source(image.Handle, &src, &dst, filterQuality))); }
public extern static sk_imagefilter_t sk_imagefilter_new_picture_for_localspace(sk_picture_t picture, ref SKRect cropRect, SKFilterQuality filterQuality);
public extern static sk_imagefilter_t sk_imagefilter_new_matrix(ref SKMatrix matrix, SKFilterQuality quality, sk_imagefilter_t input /*NULL*/);
/// <summary> /// Image Resize Async method using skiasharp wrapper /// </summary> /// <param name="sourceBitmap"></param> /// <param name="maxWidth"></param> /// <param name="maxHeight"></param> /// <param name="quality"></param> /// <returns>Resized SKBitmap with given parameter</returns> public async Task <MemoryStream> Resize(byte[] byte_image, int maxWidth, int maxHeight, SKFilterQuality quality = SKFilterQuality.Medium) { var bitmap = SKBitmap.Decode(byte_image); int height = Math.Min(maxHeight, bitmap.Height); int width = Math.Min(maxWidth, bitmap.Width); SKBitmap scaledBitmap = null; await Task.Run(() => { scaledBitmap = bitmap.Resize(new SKImageInfo(width, height), quality); }); using SKImage img = SKImage.FromBitmap(scaledBitmap); using SKData new_bitmap = img.Encode(SKEncodedImageFormat.Png, 100); MemoryStream ms = new MemoryStream(); new_bitmap.SaveTo(ms); return(ms); }
private static byte[] Resize(byte[] fileContents, int maxWidth, int maxHeight, SKFilterQuality quality = SKFilterQuality.Medium) { using MemoryStream ms = new MemoryStream(fileContents); using SKBitmap sourceBitmap = SKBitmap.Decode(ms); int height = Math.Min(maxHeight, sourceBitmap.Height); int width = Math.Min(maxWidth, sourceBitmap.Width); if (sourceBitmap.Height > maxHeight || sourceBitmap.Width > maxWidth) { if (sourceBitmap.Height > sourceBitmap.Width) { width = (int)(sourceBitmap.Width / (sourceBitmap.Height / (double)maxHeight)); } else { height = (int)(sourceBitmap.Height / (sourceBitmap.Width / (double)maxWidth)); } } using SKBitmap scaledBitmap = sourceBitmap.Resize(new SKImageInfo(width, height), quality); using SKImage scaledImage = SKImage.FromBitmap(scaledBitmap); using SKData data = scaledImage.Encode(); return(data.ToArray()); }
public extern static void sk_paint_set_filter_quality(sk_paint_t t, SKFilterQuality filterQuality);
public extern static sk_imagefilter_t sk_imagefilter_new_picture_for_localspace(sk_picture_t picture, ref SKRect cropRect, SKFilterQuality filterQuality);
public static SKImageFilter CreateMatrix(SKMatrix matrix, SKFilterQuality quality, SKImageFilter input = null) { return(GetObject <SKImageFilter>(SkiaApi.sk_imagefilter_new_matrix(&matrix, quality, input == null ? IntPtr.Zero : input.Handle))); }
public SKBitmap Resize(SKSizeI size, SKFilterQuality quality) => Resize(Info.WithSize(size), quality);
public static void DrawShadowView( ThumbnailsRenderContext ctx, ISkView view, SKImage?decorationImage = null, SKColor?backgroundColor = null, SKSize?maxSize = null, SKSize?minSize = null, SKFilterQuality resizeQuality = SKFilterQuality.None) { // max width = 128 - 12 - 12 // max height = 128 - 20 - 20 maxSize ??= new SKSize(DefaultMaxWidth, DefaultMaxHeight); minSize ??= new SKSize(0, 0); backgroundColor ??= new SKColor(0xff, 0xff, 0xff); var imageSize = ContainSize(new SKSize(view.Size.Width, view.Size.Height), maxSize.Value); var imageRect = CentralRect(imageSize); var borderSize = new SKSize(Math.Max(imageSize.Width, minSize.Value.Width), Math.Max(imageSize.Height, minSize.Value.Height)); var borderRect = CentralRect(new SKSize(borderSize.Width + 1, borderSize.Height + 1)); using (new SKAutoCanvasRestore(ctx.Canvas)) { ctx.Canvas.Clear(); using (var rectFillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = backgroundColor.Value, ImageFilter = SKImageFilter.CreateDropShadow(0, 1, 4, 4, new SKColor(136, 136, 136, 128)) }) using (var rectStrokePaint = new SKPaint { Style = SKPaintStyle.Stroke, StrokeWidth = 1, Color = new SKColor(136, 136, 136, 64), BlendMode = SKBlendMode.Src }) { // draw border using SKRoundRect roundRect = new(borderRect, 5); ctx.Canvas.DrawRoundRect(roundRect, rectFillPaint); ctx.Canvas.DrawRoundRect(roundRect, rectStrokePaint); } using (new SKAutoCanvasRestore(ctx.Canvas)) using (var imagePaint = new SKPaint { FilterQuality = resizeQuality }) using (var decorationImagePaint = new SKPaint { FilterQuality = SKFilterQuality.Medium }) { using SKRoundRect roundRect = new(imageRect, 4.5f); using (new SKAutoCanvasRestore(ctx.Canvas)) { ctx.Canvas.ClipRoundRect(roundRect); // draw image view.Draw(ctx.Canvas, imageRect, imagePaint); } if (decorationImage != null) { var decorationRect = SKRect.Create(borderRect.Right - 24.5f, borderRect.Bottom - 22.5f, 36, 36); ctx.Canvas.DrawImage(decorationImage, decorationRect, decorationImagePaint); } } } }
/// <summary> /// Generates a resized bitmap within a given rectangle. (Without causing distortion) /// </summary> /// <param name="self">Object to be extended.</param> /// <param name="width">New max width of the bitmap.</param> /// <param name="height">New max height of the bitmap.</param> /// <param name="filterQuality">Bitmaps filter quality.</param> /// <returns>A new resized bitmap instance.</returns> public static SKBitmap ResizeFixedRatio(this SKBitmap self, int width, int height, SKFilterQuality filterQuality) { double scale = Math.Min((double)width / self.Width, (double)height / self.Height); int newWidth = (int)Math.Ceiling(self.Width * scale); int newHeight = (int)Math.Ceiling(self.Height * scale); return(self.Resize(new SKSizeI(newWidth, newHeight), filterQuality)); }