public static SkiaSharp.SKBitmap CloneAsSKBitmap(SpanBitmap bmp) { if (!TryGetPixelFormat(bmp.PixelFormat, out var color, out var alpha)) { throw new ArgumentException("format", nameof(bmp)); } var img = new SkiaSharp.SKBitmap(bmp.Width, bmp.Height, color, alpha); var binfo = GetBitmapInfo(img.Info, img.RowBytes); var ptr = img.GetPixels(); if (ptr == IntPtr.Zero) { throw new ArgumentNullException(); } var dst = new SpanBitmap(ptr, binfo); dst.SetPixels(0, 0, bmp); img.NotifyPixelsChanged(); return(img); }
public SkiaMemoryManager(SkiaSharp.SKBitmap bmp) { _BitmapSource = bmp; _BitmapInfo = _Implementation.GetBitmapInfo(bmp.Info, bmp.RowBytes); var ptr = bmp.GetPixels(); if (ptr == IntPtr.Zero) { throw new ArgumentNullException(); } Initialize(new PointerBitmap(ptr, _BitmapInfo)); }
public static SpanBitmap WrapAsSpan(SkiaSharp.SKBitmap bmp, bool readOnly = false) { var wrapInfo = GetBitmapInfo(bmp.Info, bmp.RowBytes); if (readOnly) { return(new SpanBitmap(bmp.GetPixelSpan(), wrapInfo)); } var wrapBytes = bmp.GetPixels(); if (wrapBytes == IntPtr.Zero) { throw new ArgumentNullException(); } return(new SpanBitmap(wrapBytes, wrapInfo)); // should call bmp.NotifyPixelsChanged(); afterwards }
///////////////////////////////////////////////////////////////////////////////////// public static void CopyToGdiPlusBitmapSameSize( ActualImage actualImage, SkiaSharp.SKBitmap skBmp) { //agg store image buffer head-down //when copy to window bmp we here to flip //style1: copy row by row *** (fastest)*** { //System.GC.Collect(); //System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); //sss.Start(); //for (int i = 0; i < 1000; ++i) //{ int h = skBmp.Height; int w = skBmp.Width; //BitmapData bitmapData1 = bitmap.LockBits( // new Rectangle(0, 0, // w, // h), // System.Drawing.Imaging.ImageLockMode.ReadWrite, // bitmap.PixelFormat); skBmp.LockPixels(); IntPtr scan0 = skBmp.GetPixels(); int stride = actualImage.Stride; //byte[] srcBuffer = ActualImage.GetBuffer(actualImage); unsafe { TempMemPtr srcBufferPtr = ActualImage.GetBufferPtr(actualImage); //fixed (byte* bufferH = &srcBuffer[0]) byte *bufferH = (byte *)srcBufferPtr.Ptr; { byte *target = (byte *)scan0; int startRowAt = ((h - 1) * stride); for (int y = h; y > 0; --y) { //byte* src = bufferH + ((y - 1) * stride); //System.Runtime.InteropServices.Marshal.Copy( // srcBuffer,//src // startRowAt, // (IntPtr)target, // stride); AggMemMx.memcpy(target, bufferH + startRowAt, stride); startRowAt -= stride; target += stride; } } srcBufferPtr.Release(); } skBmp.UnlockPixels(); //} //sss.Stop(); //long ms = sss.ElapsedMilliseconds; } //----------------------------------- //style2: copy all, then flip again //{ // System.GC.Collect(); // System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); // sss.Start(); // for (int i = 0; i < 1000; ++i) // { // byte[] rawBuffer = ActualImage.GetBuffer(actualImage); // var bmpdata = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), // System.Drawing.Imaging.ImageLockMode.ReadOnly, // bitmap.PixelFormat); // System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // bmpdata.Scan0, rawBuffer.Length); // bitmap.UnlockBits(bmpdata); // bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); // } // sss.Stop(); // long ms = sss.ElapsedMilliseconds; //} //----------------------------------- //----------------------------------- //style3: copy row by row + //{ // System.GC.Collect(); // System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); // sss.Start(); // for (int i = 0; i < 1000; ++i) // { // int h = bitmap.Height; // int w = bitmap.Width; // BitmapData bitmapData1 = bitmap.LockBits( // new Rectangle(0, 0, // w, // h), // System.Drawing.Imaging.ImageLockMode.ReadWrite, // bitmap.PixelFormat); // IntPtr scan0 = bitmapData1.Scan0; // int stride = bitmapData1.Stride; // byte[] buffer = ActualImage.GetBuffer(actualImage); // unsafe // { // fixed (byte* bufferH = &buffer[0]) // { // byte* target = (byte*)scan0; // for (int y = h; y > 0; --y) // { // byte* src = bufferH + ((y - 1) * stride); // for (int n = stride - 1; n >= 0; --n) // { // *target = *src; // target++; // src++; // } // } // } // } // bitmap.UnlockBits(bitmapData1); // } // sss.Stop(); // long ms = sss.ElapsedMilliseconds; //} }
public void PaintMe(IntPtr hdc) { if (this.IsClosed) { return; } _rootGraphics.PrepareRender(); //--------------- _rootGraphics.IsInRenderPhase = true; #if DEBUG _rootGraphics.dbug_rootDrawingMsg.Clear(); _rootGraphics.dbug_drawLevel = 0; #endif //1. clear sk surface mySkCanvas.Clear(PixelFarm.Drawing.Color.White); //2. render to the surface UpdateAllArea(mySkCanvas, _rootGraphics.TopWindowRenderBox); //3. copy bitmap buffer from the surface and render to final hdc //----------------------------------------------- //TODO: review performance here //we should copy from unmanaged (skia bitmap) //and write to unmanaged (hdc'bitmap) SkiaSharp.SKBitmap backBmp = mySkCanvas.BackBmp; backBmp.LockPixels(); IntPtr h = backBmp.GetPixels(); int w1 = backBmp.Width; int h1 = backBmp.Height; int stride = backBmp.RowBytes; //PixelFarm.Agg.AggMemMx.memcpy() //System.Runtime.InteropServices.Marshal.Copy( // h, tmpBuffer, 0, tmpBuffer.Length // ); //copy skia pixels to our dc unsafe { //Win32.MyWin32.memcpy((byte*)memdc.PPVBits, (byte*)h, internalSizeW * 4 * internalSizwH); memdc.CopyPixelBitsToOutput((byte *)h); } backBmp.UnlockPixels(); //bitblt to target memdc.BitBltTo(hdc); //var bmpdata = tmpBmp.LockBits(new System.Drawing.Rectangle(0, 0, w1, h1), // System.Drawing.Imaging.ImageLockMode.ReadWrite, // System.Drawing.Imaging.PixelFormat.Format32bppArgb); //System.Runtime.InteropServices.Marshal.Copy(tmpBuffer, 0, bmpdata.Scan0, tmpBuffer.Length); //tmpBmp.UnlockBits(bmpdata); //using (System.Drawing.Graphics g2 = System.Drawing.Graphics.FromHdc(hdc)) //{ // g2.DrawImage(tmpBmp, 0, 0); //} //----------------------------------------------------------------------------- _rootGraphics.IsInRenderPhase = false; #if DEBUG RootGraphic visualroot = RootGraphic.dbugCurrentGlobalVRoot; if (visualroot.dbug_RecordDrawingChain) { List <dbugLayoutMsg> outputMsgs = dbugOutputWindow.dbug_rootDocDebugMsgs; outputMsgs.Clear(); outputMsgs.Add(new dbugLayoutMsg(null as RenderElement, "[" + debug_render_to_output_count + "]")); visualroot.dbug_DumpRootDrawingMsg(outputMsgs); dbugOutputWindow.dbug_InvokeVisualRootDrawMsg(); debug_render_to_output_count++; } if (dbugHelper01.dbugVE_HighlightMe != null) { dbugOutputWindow.dbug_HighlightMeNow(dbugHelper01.dbugVE_HighlightMe.dbugGetGlobalRect()); } #endif }