public static void CopyFromGdiPlusBitmapSameSize( Bitmap windowsBitmap, ActualImage actualImage) { int h = windowsBitmap.Height; int w = windowsBitmap.Width; //byte[] targetBuffer = ActualImage.GetBuffer(actualImage); BitmapData bitmapData1 = windowsBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, windowsBitmap.PixelFormat); IntPtr scan0 = bitmapData1.Scan0; int stride = bitmapData1.Stride; //TODO: review here //use buffer copy unsafe { TempMemPtr targetPtr = ActualImage.GetBufferPtr(actualImage); //target int startRowAt = ((h - 1) * stride); byte *src = (byte *)scan0; byte *targetBuffer = (byte *)targetPtr.Ptr; for (int y = h; y > 0; --y) { // byte* target = targetH + ((y - 1) * stride); //System.Runtime.InteropServices.Marshal.Copy( // (IntPtr)src,//src // targetBuffer, startRowAt, stride); AggMemMx.memcpy(targetBuffer + startRowAt, src, stride); startRowAt -= stride; src += stride; } ////////////////////////////////////////////////////////////////// //fixed (byte* targetH = &targetBuffer[0]) //{ // byte* src = (byte*)scan0; // for (int y = h; y > 0; --y) // { // byte* target = targetH + ((y - 1) * stride); // for (int n = stride - 1; n >= 0; --n) // { // *target = *src; // target++; // src++; // } // } //} } windowsBitmap.UnlockBits(bitmapData1); }
/// <summary> /// copy from actual image direct to hBmpScan0 /// </summary> /// <param name="actualImage"></param> /// <param name="hBmpScan0"></param> public static void CopyToWindowsBitmapSameSize( ActualImage actualImage, IntPtr hBmpScan0) { //1st, fast //byte[] rawBuffer = ActualImage.GetBuffer(actualImage); unsafe { TempMemPtr memPtr = ActualImage.GetBufferPtr(actualImage); AggMemMx.memcpy((byte *)hBmpScan0, (byte *)memPtr.Ptr, actualImage.Stride * actualImage.Height); memPtr.Release(); } //System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // hBmpScan0, rawBuffer.Length); }
///////////////////////////////////////////////////////////////////////////////////// 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 override void DrawImage(Image img, double left, double top) { if (img is ActualImage) { ActualImage actualImage = (ActualImage)img; //create Gdi bitmap from actual image int w = actualImage.Width; int h = actualImage.Height; switch (actualImage.PixelFormat) { case Agg.PixelFormat.ARGB32: { using (SKBitmap newBmp = new SKBitmap(actualImage.Width, actualImage.Height)) { newBmp.LockPixels(); //byte[] actualImgBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr bufferPtr = ActualImage.GetBufferPtr(actualImage); unsafe { byte *actualImgH = (byte *)bufferPtr.Ptr; AggMemMx.memcpy((byte *)newBmp.GetPixels(), actualImgH, actualImage.Stride * actualImage.Height); //System.Runtime.InteropServices.Marshal.Copy( // actualImgBuffer, // 0, // newBmp.GetPixels(), // actualImgBuffer.Length); } bufferPtr.Release(); newBmp.UnlockPixels(); } //newBmp.internalBmp.LockPixels(); //byte[] actualImgBuffer = ActualImage.GetBuffer(actualImage); //System.Runtime.InteropServices.Marshal.Copy( // actualImgBuffer, // 0, // newBmp.internalBmp.GetPixels(), // actualImgBuffer.Length); //newBmp.internalBmp.UnlockPixels(); //return newBmp; //copy data from acutal buffer to internal representation bitmap //using (MySkBmp bmp = MySkBmp.CopyFrom(actualImage)) //{ // _skCanvas.DrawBitmap(bmp.internalBmp, (float)x, (float)y); //} } break; case Agg.PixelFormat.RGB24: { } break; case Agg.PixelFormat.GrayScale8: { } break; default: throw new NotSupportedException(); } } }
public static void CopyFromGdiPlusBitmapSameSizeTo32BitsBuffer( Bitmap windowsBitmap, ActualImage actualImage) { int h = windowsBitmap.Height; int w = windowsBitmap.Width; //byte[] targetBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr targetBufferPtr = ActualImage.GetBufferPtr(actualImage); BitmapData bitmapData1 = windowsBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //read as 32 bits IntPtr scan0 = bitmapData1.Scan0; int stride = bitmapData1.Stride; //test //in this version we decided that //Agg's image should use Big-endian bytes. //so we convert the byte order for unsafe { byte *targetH = (byte *)targetBufferPtr.Ptr; int startRowAt = ((h - 1) * stride); byte *src = (byte *)scan0; for (int y = h; y > 0; --y) { //System.Runtime.InteropServices.Marshal.Copy( // (IntPtr)src,//src // targetBuffer, startRowAt, stride); AggMemMx.memcpy(targetH + startRowAt, src, stride); startRowAt -= stride; src += stride; } ////////////////////////////////////////////////////////////////// //fixed (byte* targetH = &targetBuffer[0]) //{ // byte* src = (byte*)scan0; // for (int y = h; y > 0; --y) // { // byte* target = targetH + ((y - 1) * stride); //start at first column of the current row // for (int n = stride - 1; n >= 0;) //n steps // { // //*target = *src; // //target++; // //src++; // //the win gdi+ is // *(target + 2) = *src; //R, 0->2 // *(target + 1) = *(src + 1); //G 1->1 // *(target + 0) = *(src + 2); //B 2->0 // *(target + 3) = *(src + 3); //A 3->3 // //#if !RGBA // // //eg OpenGL, // // /// <summary> // // /// order b // // /// </summary> // // public const int B = 0; // // /// <summary> // // /// order g // // /// </summary> // // public const int G = 1; // // /// <summary> // // /// order b // // /// </summary> // // public const int R = 2; // // /// <summary> // // /// order a // // /// </summary> // // public const int A = 3; // //#else // // //RGBA (Windows GDI+) // // /// <summary> // // /// order b // // /// </summary> // // public const int B = 2; // // /// <summary> // // /// order g // // /// </summary> // // public const int G = 1; // // /// <summary> // // /// order b // // /// </summary> // // public const int R = 0; // // /// <summary> // // /// order a // // /// </summary> // // public const int A = 3; // //#endif // target += 4; // src += 4; // //target++; // //src++; // n -= 4; // } // } //} } targetBufferPtr.Release(); windowsBitmap.UnlockBits(bitmapData1); }