static unsafe ComplexImage ToComplexImage(this SKImage image) { SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; if ((!MathHelpers.IsPowerOf2(width)) || (!MathHelpers.IsPowerOf2(height))) { throw new ArgumentException("Image width and height must be a power of 2."); } ComplexImage complexImage = new ComplexImage(width, height); Complex[,] data = complexImage.Data; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { byte red = *bmpPtr++; byte green = *bmpPtr++; byte blue = *bmpPtr++; bmpPtr += 1; // Ignore alpha // Assuming SKColorType.Rgba8888 - used by iOS and Android // (UWP uses SKColorType.Bgra8888) byte result = (byte)(0.2126 * red + 0.7152 * green + 0.0722 * blue); data[row, col].Re = (float)result / 255; } } return(complexImage); }
public static unsafe SKPixmap ToSKPixmap(this ComplexImage complexImage, SKImage image) { SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; Complex[,] data = complexImage.Data; double scale = (complexImage.IsFourierTransformed) ? Math.Sqrt(width * height) : 1; bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { // Assuming SKColorType.Rgba8888 - used by iOS and Android // (UWP uses SKColorType.Bgra8888) byte result = (byte)Math.Max(0, Math.Min(255, data[row, col].Magnitude * scale * 255)); * bmpPtr++ = result; // red * bmpPtr++ = result; // green * bmpPtr++ = result; // blue bmpPtr += 1; // Ignore alpha } } return(pixmap); }
public static Bitmap ToBitmap(this SKImage skiaImage) { using (var pixmap = skiaImage.PeekPixels()) { return(pixmap.ToBitmap()); } }
public static unsafe SKPixmap ToGreyscale(this SKImage image) { SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; byte * tempPtr; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { tempPtr = bmpPtr; byte red = *bmpPtr++; byte green = *bmpPtr++; byte blue = *bmpPtr++; byte alpha = *bmpPtr++; // Assuming SKColorType.Rgba8888 - used by iOS and Android // (UWP uses SKColorType.Bgra8888) byte result = (byte)(0.2126 * red + 0.7152 * green + 0.0722 * blue); bmpPtr = tempPtr; *bmpPtr++ = result; // red *bmpPtr++ = result; // green *bmpPtr++ = result; // blue *bmpPtr++ = alpha; // alpha } } return(pixmap); }
public static unsafe SKPixmap ToSepia(this SKImage image) { SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; byte * tempPtr; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { tempPtr = bmpPtr; byte red = *bmpPtr++; byte green = *bmpPtr++; byte blue = *bmpPtr++; byte alpha = *bmpPtr++; // Assuming SKColorType.Rgba8888 - used by iOS and Android // (UWP uses SKColorType.Bgra8888) byte intensity = (byte)(0.299 * red + 0.587 * green + 0.114 * blue); bmpPtr = tempPtr; *bmpPtr++ = (byte)((intensity > 206) ? 255 : intensity + 49); // red *bmpPtr++ = (byte)((intensity < 14) ? 0 : intensity - 14); // green *bmpPtr++ = (byte)((intensity < 56) ? 0 : intensity - 56); // blue *bmpPtr++ = alpha; // alpha } } return(pixmap); }
public static SKImage Resize(this SKImage input, int width, int height) { var imageInfo = new SKImageInfo(width, height); SKImage image = SKImage.Create(imageInfo); input.ScalePixels(image.PeekPixels(), SKFilterQuality.High); return(image); }
public static Bitmap ToBitmap(this SKImage skiaImage) { using (var pixmap = skiaImage.PeekPixels()) { var bmp = pixmap.ToBitmap(); GC.KeepAlive(skiaImage); return(bmp); } }
public static SKImage ToSKImage(this Bitmap bitmap) { SKImage sKImage = SKImage.Create(new SKImageInfo(bitmap.Width, bitmap.Height)); using (SKPixmap pixmap = sKImage.PeekPixels()) { bitmap.ToSKPixmap(pixmap); return(sKImage); } }
private void RenderImageToTexture2D(SKImage image, GraphicsDevice graphicsDevice) { var pixelMap = image.PeekPixels(); var pointer = pixelMap.GetPixels(); Marshal.Copy(pointer, _rawCanvasPixels, 0, _rawCanvasPixels.Length); _graphTexture ??= new Texture2D(graphicsDevice, image.Width, image.Height); _graphTexture.SetData(_rawCanvasPixels); }
public static string Save(SKImage image) { var guid = Guid.NewGuid().ToString(); using (var file = System.IO.File.Create(Path.Combine(rootPath, guid))) { using var pixmap = image.PeekPixels(); pixmap.Encode(file, SKPngEncoderOptions.Default); } return(guid); }
public static Texture2D RenderImageToTexture2D(SKImage image, GraphicsDevice graphicsDevice) { var pixelMap = image.PeekPixels(); var pointer = pixelMap.GetPixels(); var pixels = new byte[image.Height * pixelMap.RowBytes]; Marshal.Copy(pointer, pixels, 0, pixels.Length); var texture = new Texture2D(graphicsDevice, image.Width, image.Height); texture.SetData(pixels); return(texture); }
public ImmutableBitmap(ImmutableBitmap src, PixelSize destinationSize, BitmapInterpolationMode interpolationMode) { SKImageInfo info = new SKImageInfo(destinationSize.Width, destinationSize.Height, SKColorType.Bgra8888); SKImage output = SKImage.Create(info); src._image.ScalePixels(output.PeekPixels(), interpolationMode.ToSKFilterQuality()); _image = output; PixelSize = new PixelSize(_image.Width, _image.Height); // TODO: Skia doesn't have an API for DPI. Dpi = new Vector(96, 96); }
public static SKImage CaptureRegion(int x, int y, int width, int height) { IntPtr sourceDC = IntPtr.Zero; IntPtr targetDC = IntPtr.Zero; IntPtr compatibleBitmapHandle = IntPtr.Zero; // create the final SkiaSharp image SKImage image = SKImage.Create(new SKImageInfo(width, height)); SKPixmap pixmap = image.PeekPixels(); try { // gets the main desktop and all open windows sourceDC = User32.GetDC(User32.GetDesktopWindow()); targetDC = Gdi32.CreateCompatibleDC(sourceDC); // create a bitmap compatible with our target DC compatibleBitmapHandle = Gdi32.CreateCompatibleBitmap(sourceDC, width, height); // gets the bitmap into the target device context Gdi32.SelectObject(targetDC, compatibleBitmapHandle); // copy from source to destination Gdi32.BitBlt(targetDC, 0, 0, width, height, sourceDC, x, y, Gdi32.TernaryRasterOperations.SRCCOPY); // create the info structure Gdi32.BITMAPINFOHEADER bmi = new Gdi32.BITMAPINFOHEADER(); bmi.biPlanes = 1; bmi.biBitCount = 32; bmi.biWidth = width; bmi.biHeight = -height; bmi.biCompression = Gdi32.BitmapCompressionMode.BI_RGB; // read the raw pixels into the pixmap for the image Gdi32.GetDIBits(targetDC, compatibleBitmapHandle, 0, height, pixmap.GetPixels(), bmi, Gdi32.DIB_Color_Mode.DIB_RGB_COLORS); } finally { Gdi32.DeleteObject(compatibleBitmapHandle); User32.ReleaseDC(IntPtr.Zero, sourceDC); User32.ReleaseDC(IntPtr.Zero, targetDC); } return(image); }
protected virtual SKImage ConvertProfile(SKImage data, float width, float height) { using SKImage srcImg = data; SKImageInfo info = new SKImageInfo((int)width, (int)height, SKImageInfo.PlatformColorType, SKAlphaType.Opaque, SKColorSpace.CreateSrgb()); // this is the important part. set the destination ColorSpace as // `SKColorSpace.CreateSrgb()`. Skia will then be able to automatically convert // the original CMYK colorspace, to this new sRGB colorspace. SKImage newImg = SKImage.Create(info); srcImg.ScalePixels(newImg.PeekPixels(), SKFilterQuality.None); // Remove transparency var bitmap = RemoveTransparency(srcImg); newImg = SKImage.FromBitmap(bitmap); // now when doing this resize, Skia knows the original ColorSpace, and the // destination ColorSpace, and converts the colors from CMYK to sRGB. return(newImg); }
static unsafe void ToYCbCrAArrays(this SKImage image, float[,] y, float[,] cb, float[,] cr, float[,] a) { if (y == null) { throw new ArgumentException("y can't be null"); } if (cb == null) { throw new ArgumentException("cb can't be null"); } if (cr == null) { throw new ArgumentException("cr can't be null"); } if (a == null) { throw new ArgumentException("a can't be null"); } SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { byte red = *bmpPtr++; byte green = *bmpPtr++; byte blue = *bmpPtr++; byte alpha = *bmpPtr++; y[col, row] = (0.2990f * red + 0.5870f * green + 0.1140f * blue + 0.5f); cb[col, row] = (-0.1687f * red - 0.3313f * green + 0.5000f * blue + 127.5f + 0.5f); cr[col, row] = (0.5000f * red - 0.4187f * green - 0.0813f * blue + 127.5f + 0.5f); a[col, row] = alpha; } } }
private static bool[,] GetDotArray(SKImage image, int rowCount, int colCount) { var path = new bool[rowCount, colCount]; var startPoint = new SKPoint(); var pixels = image.PeekPixels(); var rectSize = new SKPoint(image.Width / (float)colCount, image.Height / (float)rowCount); for (var i = 0; i < rowCount; i++) { startPoint.X = 0; for (var j = 0; j < colCount; j++) { var pixelColor = pixels.GetPixelColor((int)(startPoint.X + rectSize.X / 2), (int)(startPoint.Y + rectSize.Y / 2)); path[i, j] = pixelColor.Alpha > 0; startPoint.X += rectSize.X; } startPoint.Y += rectSize.Y; } pixels.Dispose(); return(path); }
/// <summary> /// Load an image from the phone /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private async void LoadImage(object sender, EventArgs args) { IPhotoLibrary photoLibrary = DependencyService.Get <IPhotoLibrary>(); using (Stream stream = await photoLibrary.PickPhotoAsync()) { if (stream != null) { SKBitmap loaded = SKBitmap.Decode(stream); if (loaded != null) { if (animation) { StopAccelerometer(); } //Set the image dimensions width = (int)imgGenerated.CanvasSize.ToFormsSize().Width; height = (int)imgGenerated.CanvasSize.ToFormsSize().Height; int oldSize = width; if (width > height) { oldSize = height; } int size = oldSize; for (int i = 1; i < oldSize; i <<= 1) { size = i; } width = size; height = size; generator.SetDimensions(width, height); // Resize the loaded image //source: https://stackoverflow.com/questions/48422724/fastest-way-to-scale-an-skimage-skiasharp SKImageInfo info = new SKImageInfo(width, height, SKColorType.Rgba8888); SKImage output = SKImage.Create(info); loaded.ScalePixels(output.PeekPixels(), SKFilterQuality.None); imgBitmap = SKBitmap.FromImage(output); skRect = new SKRect(0, 0, oldSize, oldSize); generator.Load(imgBitmap); imgGenerated.InvalidateSurface(); if (animation) { StartAccelerometer(); } } } } }
async void OnSavePhotoClicked(object sender, EventArgs e) { await Navigation.PushModalAsync(new NavigationPage(new SavePhotoPage(image.PeekPixels()))); }
public static unsafe SKPixmap OtsuThreshold(this SKImage image) { SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; int[] intHistogram = new int[256]; double[] histogram = new double[256]; int threshold = 0; // Build a histogram for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { byte red = *bmpPtr++; byte green = *bmpPtr++; byte blue = *bmpPtr++; // Assuming SKColorType.Rgba8888 - used by iOS and Android // (UWP uses SKColorType.Bgra8888) int result = (byte)(0.2126 * red + 0.7152 * green + 0.0722 * blue); intHistogram[result]++; } } int pixelCount = width * height; double imageMean = 0; for (int i = 0; i < 256; i++) { histogram[i] = (double)intHistogram[i] / pixelCount; imageMean += histogram[i] * i; } double max = double.MinValue; double c1Prob = 0; double c2Prob = 1; double c1MeanInit = 0; for (int i = 0; i < 256 && c2Prob > 0; i++) { double c1Mean = c1MeanInit; double c2Mean = (imageMean - (c1Mean * c1Prob)) / c2Prob; double classVariance = c1Prob * (1.0 - c1Prob) * Math.Pow(c1Mean - c2Mean, 2); if (classVariance > max) { max = classVariance; threshold = i; } c1MeanInit *= c1Prob; c1Prob += histogram[i]; c2Prob -= histogram[i]; c1MeanInit += (double)i * (double)histogram[i]; if (Math.Abs(c1Prob) > 0) { c1MeanInit /= c1Prob; } } bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); // Apply threshold for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { if (*bmpPtr <= threshold) { *bmpPtr++ = 0; // red *bmpPtr++ = 0; // green *bmpPtr++ = 0; // blue } else { *bmpPtr++ = 255; // red *bmpPtr++ = 255; // green *bmpPtr++ = 255; // blue } bmpPtr += 1; } } return(pixmap); }
static unsafe SKPixmap ToRGBAPixmap(this SKImage image, float[,] y, float[,] cb, float[,] cr, float[,] a) { if (y == null) { throw new ArgumentException("y can't be null"); } if (cb == null) { throw new ArgumentException("cb can't be null"); } if (cr == null) { throw new ArgumentException("cr can't be null"); } if (a == null) { throw new ArgumentException("a can't be null"); } SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { float yValue = y[col, row]; float cbValue = cb[col, row] - 127.5f; float crValue = cr[col, row] - 127.5f; float aValue = a[col, row]; int red = (int)(yValue + 1.40200f * crValue + 0.5f); int green = (int)(yValue - 0.34414f * cbValue - 0.71417f * crValue + 0.5f); int blue = (int)(yValue + 1.77200f * cbValue + 0.5f); int alpha = (int)aValue; if (red < 0) { red = 0; } else if (red > 255) { red = 255; } if (green < 0) { green = 0; } else if (green > 255) { green = 255; } if (blue < 0) { blue = 0; } else if (blue > 255) { blue = 255; } if (alpha < 0) { alpha = 0; } else if (alpha > 255) { alpha = 255; } *bmpPtr++ = (byte)red; *bmpPtr++ = (byte)green; *bmpPtr++ = (byte)blue; *bmpPtr++ = (byte)alpha; } } return(pixmap); }