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 void WithMethodsDoNotModifySource() { var info = new SKImageInfo(100, 30, SKColorType.Rgb565, SKAlphaType.Unpremul); var pixmap = new SKPixmap(info, (IntPtr)123); Assert.Equal(SKColorType.Rgb565, pixmap.ColorType); Assert.Equal((IntPtr)123, pixmap.GetPixels()); var copy = pixmap.WithColorType(SKColorType.Gray8); Assert.Equal(SKColorType.Rgb565, pixmap.ColorType); Assert.Equal((IntPtr)123, pixmap.GetPixels()); Assert.Equal(SKColorType.Gray8, copy.ColorType); Assert.Equal((IntPtr)123, copy.GetPixels()); }
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); }
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 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); }
// CGImage public static void ToSKPixmap(this CGImage cgImage, SKPixmap pixmap) { using (var colorSpace = CGColorSpace.CreateDeviceRGB()) using (var context = new CGBitmapContext(pixmap.GetPixels(), pixmap.Width, pixmap.Height, 8, pixmap.RowBytes, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big)) { context.DrawImage(new CGRect(0, 0, cgImage.Width, cgImage.Height), cgImage); } }
protected override SKData OnEncode(SKPixmap pixmap) { DidEncode++; EncodedInfo = pixmap.Info; return(SKData.CreateCopy(pixmap.GetPixels(), (ulong)pixmap.Info.BytesSize)); }
// CIImage #if !__WATCHOS__ public static void ToSKPixmap(this CIImage ciImage, SKPixmap pixmap) { using (var colorSpace = CGColorSpace.CreateDeviceRGB()) using (var context = new CIContext(null)) { context.RenderToBitmap(ciImage, pixmap.GetPixels(), pixmap.RowBytes, ciImage.Extent, (int)CIFormat.kRGBA8, colorSpace); } }
public static void ToSKPixmap(this Pixbuf pixbuf, SKPixmap pixmap) { // TODO: maybe keep the same color types where we can, instead of just going to the platform default var info = new SKImageInfo(pixbuf.Width, pixbuf.Height); using (var temp = new SKPixmap(info, pixbuf.Pixels)) { temp.ReadPixels(pixmap); if (info.ColorType == SKColorType.Bgra8888) { SKSwizzle.SwapRedBlue(pixmap.GetPixels(), info.Width * info.Height); } } }
public static void ToSKPixmap(this BitmapSource bitmap, SKPixmap pixmap) { if (pixmap.ColorType == SKImageInfo.PlatformColorType) { var info = pixmap.Info; var converted = new FormatConvertedBitmap(bitmap, PixelFormats.Pbgra32, null, 0); converted.CopyPixels(new Int32Rect(0, 0, info.Width, info.Height), pixmap.GetPixels(), info.BytesSize, info.RowBytes); } else { using (var tempImage = bitmap.ToSKImage()) { tempImage.ReadPixels(pixmap, 0, 0); } } }
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); }
public static void ToSKPixmap(this BitmapSource bitmap, SKPixmap pixmap) { if (pixmap.ColorType == SKImageInfo.PlatformColorType) { var info = pixmap.Info; var converted = new FormatConvertedBitmap(bitmap, PixelFormats.Pbgra32, null, 0); converted.CopyPixels(new Int32Rect(0, 0, info.Width, info.Height), pixmap.GetPixels(), info.BytesSize, info.RowBytes); } else { // we have to copy the pixels into a format that we understand // and then into a desired format // TODO: we can still do a bit more for other cases where the color types are the same using var tempImage = bitmap.ToSKImage(); tempImage.ReadPixels(pixmap, 0, 0); } }
public static CGImage ToCGImage(this SKPixmap skiaPixmap) { var info = skiaPixmap.Info; CGImage cgImage; using (var provider = new CGDataProvider(skiaPixmap.GetPixels(), info.BytesSize)) using (var colorSpace = CGColorSpace.CreateDeviceRGB()) { cgImage = new CGImage( info.Width, info.Height, 8, info.BitsPerPixel, info.RowBytes, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big, provider, null, false, CGColorRenderingIntent.Default); } return(cgImage); }
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; } } }
public static void ToSKPixmap(this Bitmap bitmap, SKPixmap pixmap) { if (pixmap.ColorType == SKImageInfo.PlatformColorType) { SKImageInfo info = pixmap.Info; using (Bitmap image = new Bitmap(info.Width, info.Height, info.RowBytes, PixelFormat.Format32bppPArgb, pixmap.GetPixels())) { using (Graphics graphics = Graphics.FromImage(image)) { graphics.Clear(Color.Transparent); graphics.DrawImageUnscaled(bitmap, 0, 0); } } } else { using (SKImage sKImage = bitmap.ToSKImage()) { sKImage.ReadPixels(pixmap, 0, 0); } } }
public static void ToSKPixmap(this System.Drawing.Bitmap bitmap, SKPixmap pixmap) { // TODO: maybe keep the same color types where we can, instead of just going to the platform default if (pixmap.ColorType == SKImageInfo.PlatformColorType) { var info = pixmap.Info; using (var tempBitmap = new System.Drawing.Bitmap(info.Width, info.Height, info.RowBytes, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, pixmap.GetPixels())) using (var gr = System.Drawing.Graphics.FromImage(tempBitmap)) { gr.DrawImageUnscaled(bitmap, 0, 0); } } else { // we have to copy the pixels into a format that we understand // and then into a desired format // TODO: we can still do a bit more for other cases where the color types are the same using (var tempImage = bitmap.ToSKImage()) { tempImage.ReadPixels(pixmap, 0, 0); } } }
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); }