public IBitmap Apply(BitmapPixelData bmData) { int width = bmData.Width; int height = bmData.Height; PixelFormat dstPixelFormat = FormatTranslations[bmData.PixelFormat]; // create new image of required format IBitmap dstImage = (dstPixelFormat == PixelFormat.Gray8) ? Helper.CreateGrayscaleImage(width, height) : GraphicsEngine.Current.Engine.CreateBitmap(width, height, dstPixelFormat); // lock destination bitmap data BitmapPixelData dstData = dstImage.LockBitmapPixelData( BitmapLockMode.ReadWrite, dstPixelFormat); try { ProcessFilter(bmData, dstData); } finally { // unlock destination images dstImage.UnlockBitmapPixelData(dstData); } return(dstImage); }
public void UnlockBitmapPixelData(BitmapPixelData bitmapPixelData) { try { if (bitmapPixelData.PixelFormat != PixelFormat.Rgb32 && bitmapPixelData.PixelFormat != PixelFormat.Rgba32 && bitmapPixelData.PixelFormat != PixelFormat.Gray8) { if (bitmapPixelData.LockMode == BitmapLockMode.WriteOnly || bitmapPixelData.LockMode == BitmapLockMode.ReadWrite) { bitmapPixelData.CopyToArgb(_bitmap.GetPixels()); } } } finally { if (bitmapPixelData is SkiaBitmapPixelData && ((SkiaBitmapPixelData)bitmapPixelData).FreeMemory == true && bitmapPixelData.Scan0 != IntPtr.Zero) { Marshal.FreeHGlobal(bitmapPixelData.Scan0); } } }
public void UnlockBitmapPixelData(BitmapPixelData bitmapPixelData) { if (bitmapPixelData is GdiBitmapPixelData) { _bitmap.UnlockBits(((GdiBitmapPixelData)bitmapPixelData).BitmapData); } }
public bool IsEmptyBitmap(IBitmap bitmap, ArgbColor backgroundColor) { BitmapPixelData bmData = null; try { bmData = bitmap.LockBitmapPixelData(BitmapLockMode.ReadOnly, PixelFormat.Rgba32); int stride = bmData.Stride; IntPtr Scan0 = bmData.Scan0; int backgroundColorValue = ArgbColor.FromArgb( backgroundColor.A, backgroundColor.R, backgroundColor.G, backgroundColor.B).ToArgb(); unsafe { byte *p = (byte *)(void *)Scan0; int nOffset = stride - bitmap.Width * 4; for (int y = 0; y < bitmap.Height; ++y) { for (int x = 0; x < bitmap.Width; ++x) { byte blue = p[0]; byte green = p[1]; byte red = p[2]; byte alpha = p[3]; if (alpha != 0) // Not transparent { int pixelValue = ArgbColor.FromArgb(alpha, red, green, blue).ToArgb(); if (!pixelValue.Equals(backgroundColorValue)) { return(false); } } p += 4; } p += nOffset; } } } finally { if (bitmap != null && bmData != null) { bitmap.UnlockBitmapPixelData(bmData); } } return(true); }
public double GetStdDev(IBitmap bitmap) { double total = 0, totalVariance = 0; int count = 0; double stdDev = 0; // First get all the bytes BitmapPixelData bmData = null; try { bmData = bitmap.LockBitmapPixelData(BitmapLockMode.ReadOnly, bitmap.PixelFormat); int stride = bmData.Stride; IntPtr Scan0 = bmData.Scan0; unsafe { byte *p = (byte *)(void *)Scan0; int nOffset = stride - bitmap.Width * 3; for (int y = 0; y < bitmap.Height; ++y) { for (int x = 0; x < bitmap.Width; ++x) { count++; byte blue = p[0]; byte green = p[1]; byte red = p[2]; int pixelValue = ArgbColor.FromArgb(0, red, green, blue).ToArgb(); total += pixelValue; double avg = total / count; totalVariance += Math.Pow(pixelValue - avg, 2); stdDev = Math.Sqrt(totalVariance / count); p += 3; } p += nOffset; } } } finally { if (bmData != null) { bitmap.UnlockBitmapPixelData(bmData); } } return(stdDev); }
static public void CopyToArgb(this BitmapPixelData bitmapPixelData, IntPtr targetScan0) { unsafe { //var td = DateTime.Now; if (bitmapPixelData.PixelFormat == PixelFormat.Gray8) { byte *source = (byte *)bitmapPixelData.Scan0.ToPointer(); uint *target = (uint *)targetScan0.ToPointer(); for (int row = 0, row_to = bitmapPixelData.Height; row < row_to; row++) { for (int col = 0, col_to = bitmapPixelData.Width; col < col_to; col++) { *target++ = MakePixel(*source, *source, *source++, 0xFF); } } } else if (bitmapPixelData.PixelFormat == PixelFormat.Rgb24) { byte *source = (byte *)bitmapPixelData.Scan0.ToPointer(); uint *target = (uint *)targetScan0.ToPointer(); for (int row = 0, row_to = bitmapPixelData.Height; row < row_to; row++) { for (int col = 0, col_to = bitmapPixelData.Width; col < col_to; col++) { *target++ = MakePixel(*source++, *source++, *source++, 0xFF); } } } else { byte *source = (byte *)bitmapPixelData.Scan0.ToPointer(); uint *target = (uint *)targetScan0.ToPointer(); for (int row = 0, row_to = bitmapPixelData.Height; row < row_to; row++) { for (int col = 0, col_to = bitmapPixelData.Width; col < col_to; col++) { *target++ = MakePixel(*source++, *source++, *source++, *source++); } } } //var ms = (DateTime.Now - td).TotalMilliseconds; //System.IO.File.AppendAllText("C:\\temp\\CopyToArgb.txt", $"CopyToArgb: { ms }ms{ Environment.NewLine }"); } }
static public void ReadFromArgb(this BitmapPixelData bitmapPixelData, IntPtr sourceScan0) { unsafe { if (bitmapPixelData.PixelFormat == PixelFormat.Gray8) { byte *source = (byte *)sourceScan0.ToPointer(); byte *target = (byte *)bitmapPixelData.Scan0.ToPointer(); for (int row = 0, row_to = bitmapPixelData.Height; row < row_to; row++) { for (int col = 0, col_to = bitmapPixelData.Width; col < col_to; col++) { *target++ = (byte)(((*source++) + (*source++) + (*source++)) / 3); source++; } } } else if (bitmapPixelData.PixelFormat == PixelFormat.Rgb24) { byte *source = (byte *)sourceScan0.ToPointer(); byte *target = (byte *)bitmapPixelData.Scan0.ToPointer(); for (int row = 0, row_to = bitmapPixelData.Height; row < row_to; row++) { for (int col = 0, col_to = bitmapPixelData.Width; col < col_to; col++) { *target++ = *source++; *target++ = *source++; *target++ = *source++; source++; } } } else { uint *source = (uint *)sourceScan0.ToPointer(); uint *target = (uint *)bitmapPixelData.Scan0.ToPointer(); for (int row = 0, row_to = bitmapPixelData.Height; row < row_to; row++) { for (int col = 0, col_to = bitmapPixelData.Width; col < col_to; col++) { *target++ = *source++; } } } } }
protected override unsafe void ProcessFilter(BitmapPixelData sourceData, BitmapPixelData destinationData) { // get width and height int width = sourceData.Width; int height = sourceData.Height; PixelFormat srcPixelFormat = sourceData.PixelFormat; if ( (srcPixelFormat == PixelFormat.Rgb24) || (srcPixelFormat == PixelFormat.Rgb32) || (srcPixelFormat == PixelFormat.Rgba32)) { int pixelSize = (srcPixelFormat == PixelFormat.Rgb24) ? 3 : 4; int srcOffset = sourceData.Stride - width * pixelSize; int dstOffset = destinationData.Stride - width; int rc = (int)(0x10000 * RedCoefficient); int gc = (int)(0x10000 * GreenCoefficient); int bc = (int)(0x10000 * BlueCoefficient); // make sure sum of coefficients equals to 0x10000 while (rc + gc + bc < 0x10000) { bc++; } // do the job byte *src = (byte *)sourceData.Scan0.ToPointer(); byte *dst = (byte *)destinationData.Scan0.ToPointer(); // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, src += pixelSize, dst++) { *dst = (byte)((rc * src[RGB.R] + gc * src[RGB.G] + bc * src[RGB.B]) >> 16); } src += srcOffset; dst += dstOffset; } } }
static public Bitmap ToGdiBitmap(this IBitmap iBitmap) { if (iBitmap.EngineElement == null) { return(new Bitmap(1, 1)); } if (iBitmap?.EngineElement is Bitmap) { return((Bitmap)iBitmap.EngineElement); } BitmapPixelData bmPixelData = null; try { bmPixelData = iBitmap.LockBitmapPixelData(BitmapLockMode.Copy, PixelFormat.Rgba32); var bm = new Bitmap(bmPixelData.Width, bmPixelData.Height, bmPixelData.Stride, System.Drawing.Imaging.PixelFormat.Format32bppArgb, bmPixelData.Scan0); bmPixelData.Scan0 = IntPtr.Zero; // Don't give it back... //bm.Save($"C:\\temp\\gr_{ Guid.NewGuid().ToString() }.png", System.Drawing.Imaging.ImageFormat.Png); return(bm); } finally { if (bmPixelData != null) { iBitmap.UnlockBitmapPixelData(bmPixelData); } } }
public void Encode(IBitmap bitmap, Stream stream, ImageFormat format, int quality = 0) { if (bitmap == null) { throw new ArgumentException("Bitmap is NULL"); } if (bitmap.EngineElement is System.Drawing.Bitmap) { ((System.Drawing.Bitmap)bitmap.EngineElement).Save(stream, format.ToImageFormat()); } else { BitmapPixelData pixelData = null; try { pixelData = bitmap.LockBitmapPixelData(BitmapLockMode.ReadWrite, bitmap.PixelFormat); using (var bm = new System.Drawing.Bitmap( pixelData.Width, pixelData.Height, pixelData.Stride, pixelData.PixelFormat.ToGdiPixelFormat(), pixelData.Scan0)) { bm.Save(stream, format.ToImageFormat()); } } finally { if (pixelData != null) { bitmap.UnlockBitmapPixelData(pixelData); } } } }
protected abstract unsafe void ProcessFilter(BitmapPixelData sourceData, BitmapPixelData destinationData);
protected override unsafe void ProcessFilter(BitmapPixelData sourceData, BitmapPixelData destinationData) { // get width and height int width = sourceData.Width; int height = sourceData.Height; int pixelSize = Helper.GetPixelFormatSize(sourceData.PixelFormat) / 8; if ((channel == RGB.A) && (pixelSize != 4) && (pixelSize != 8)) { throw new Exception("Can not extract alpha channel from none ARGB image."); } if (pixelSize <= 4) { int srcOffset = sourceData.Stride - width * pixelSize; int dstOffset = destinationData.Stride - width; // do the job byte *src = (byte *)sourceData.Scan0.ToPointer(); byte *dst = (byte *)destinationData.Scan0.ToPointer(); // allign source pointer to the required channel src += channel; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src += pixelSize, dst++) { *dst = *src; } src += srcOffset; dst += dstOffset; } } else { pixelSize /= 2; byte *srcBase = (byte *)sourceData.Scan0.ToPointer(); byte *dstBase = (byte *)destinationData.Scan0.ToPointer(); int srcStride = sourceData.Stride; int dstStride = destinationData.Stride; // for each line for (int y = 0; y < height; y++) { ushort *src = (ushort *)(srcBase + y * srcStride); ushort *dst = (ushort *)(dstBase + y * dstStride); // allign source pointer to the required channel src += channel; // for each pixel for (int x = 0; x < width; x++, src += pixelSize, dst++) { *dst = *src; } } } }