public static unsafe MemBitmap CreateFromCopy(int width, int height, IntPtr totalBuffer, int totalLen, bool doFlipY = false) { var bmp = new MemBitmap(width, height); #if DEBUG bmp._dbugNote = "MemBitmap.CreateFromCopy"; #endif //System.Runtime.InteropServices.Marshal.Copy(totalBuffer, bmp._pixelBuffer, 0, totalLen); MemMx.memcpy((byte *)(bmp._pixelBuffer), (byte *)totalBuffer, totalLen); //if (doFlipY) //{ // //flip vertical Y // int[] totalBufferFlipY = new int[totalBuffer.Length]; // int srcRowIndex = height - 1; // int strideInBytes = width * 4;//32 bpp // for (int i = 0; i < height; ++i) // { // //copy each row from src to dst // System.Buffer.BlockCopy(totalBuffer, strideInBytes * srcRowIndex, totalBufferFlipY, strideInBytes * i, strideInBytes); // srcRowIndex--; // } // totalBuffer = totalBufferFlipY; //} //unsafe //{ //} return(bmp); }
public override void SaveImage(MemBitmap bitmap, string filename, OutputImageFormat outputFormat, object saveParameters) { //TODO: resolve filename here!!! using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(bitmap.Width, bitmap.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { var bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); unsafe { byte *ptr = (byte *)MemBitmap.GetBufferPtr(bitmap).Ptr; MemMx.memcpy((byte *)bmpdata.Scan0, ptr, bmpdata.Stride * bmp.Height); } bmp.UnlockBits(bmpdata); //save to stream System.Drawing.Imaging.ImageFormat format = null; switch (outputFormat) { case OutputImageFormat.Default: throw new NotSupportedException(); case OutputImageFormat.Jpeg: format = System.Drawing.Imaging.ImageFormat.Jpeg; break; case OutputImageFormat.Png: format = System.Drawing.Imaging.ImageFormat.Png; break; } bmp.Save(filename, format); } }
public static int[] CopyImgBuffer(this MemBitmap memBmp, int width, int height) { //calculate stride for the width int destStride = MemBitmap.CalculateStride(width, PixelFormat.ARGB32); int newBmpW = destStride / 4; int[] buff2 = new int[newBmpW * height]; unsafe { using (TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(memBmp)) { byte *srcBuffer = (byte *)srcBufferPtr.Ptr; int srcIndex = 0; int srcStride = memBmp.Stride; fixed(int *destHead = &buff2[0]) { byte *destHead2 = (byte *)destHead; for (int line = 0; line < height; ++line) { //System.Runtime.InteropServices.Marshal.Copy(srcBuffer, srcIndex, (IntPtr)destHead2, destStride); MemMx.memcpy((byte *)destHead2, srcBuffer + srcIndex, destStride); srcIndex += srcStride; destHead2 += destStride; } } } } return(buff2); }
public static void Main() { //TEST //this is low-level scanline rasterizer //1. create vertex store VertexStore vxs = new VertexStore(); vxs.AddMoveTo(10, 10); vxs.AddLineTo(50, 10); vxs.AddLineTo(50, 50); vxs.AddLineTo(10, 50); vxs.AddCloseFigure(); //2. create scanline rasterizer ScanlineRasterizer sclineRas = new ScanlineRasterizer(); sclineRas.AddPath(vxs); //3. create destination bitmap DestBitmapRasterizer destBmpRasterizer = new DestBitmapRasterizer(); //4. create 32bit rgba bitmap blender MyBitmapBlender myBitmapBlender = new MyBitmapBlender(); //5. create output bitmap using (MemBitmap membitmap = new MemBitmap(800, 600)) { //6. attach target bitmap to bitmap blender myBitmapBlender.Attach(membitmap); //7. rasterizer sends the vector content inside sclineRas // to the bitmap blender and destBmpRasterizer.RenderWithColor(myBitmapBlender, //blender+ output sclineRas, //with vectors input inside new ScanlinePacked8(), Color.Red); //8. the content inside membitmap is just color image buffer // you can copy it to other image object (eg SkImage, Gdi+ image etc) //... example ... using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(membitmap.Width, membitmap.Height)) { IntPtr mem_ptr = membitmap.GetRawBufferHead(); System.Drawing.Imaging.BitmapData bmpdata = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); unsafe { MemMx.memcpy((byte *)bmpdata.Scan0, (byte *)mem_ptr, membitmap.Width * membitmap.Height * 4); } bmp.UnlockBits(bmpdata); bmp.Save("test01.png"); } } }
public static void CopyFromGdiPlusBitmapSameSize( Bitmap windowsBitmap, MemBitmap 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 { //target TempMemPtr targetMemPtr = MemBitmap.GetBufferPtr(actualImage); byte * target = (byte *)targetMemPtr.Ptr; int startRowAt = ((h - 1) * stride); byte * src = (byte *)scan0; for (int y = h; y > 0; --y) { // byte* target = targetH + ((y - 1) * stride); //System.Runtime.InteropServices.Marshal.Copy( // (IntPtr)src,//src // targetBuffer, startRowAt, stride); MemMx.memcpy(target + startRowAt, src, stride); startRowAt -= stride; src += stride; } targetMemPtr.Dispose(); ////////////////////////////////////////////////////////////////// //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); }
public static MemBitmap CreateFromCopy(int width, int height, int len, IntPtr anotherNativePixelBuffer) { var memBmp = new MemBitmap(width, height); #if DEBUG memBmp._dbugNote = "MemBitmap.CreateFromCopy"; #endif unsafe { MemMx.memcpy((byte*)memBmp._pixelBuffer, (byte*)anotherNativePixelBuffer, len); } return memBmp; }
public static MemBitmap CreateFromCopy(MemBitmap another) { var memBmp = new MemBitmap(another.Width, another.Height); #if DEBUG memBmp._dbugNote = "MemBitmap.CreateFromCopy"; #endif unsafe { MemMx.memcpy((byte*)memBmp._pixelBuffer, (byte*)another._pixelBuffer, another._pixelBufferInBytes); } return memBmp; }
/// <summary> /// copy from actual image direct to hBmpScan0 /// </summary> /// <param name="actualImage"></param> /// <param name="hBmpScan0"></param> public static void CopyToWindowsBitmapSameSize( MemBitmap actualImage, IntPtr hBmpScan0) { //1st, fast //byte[] rawBuffer = ActualImage.GetBuffer(actualImage); unsafe { TempMemPtr memPtr = MemBitmap.GetBufferPtr(actualImage); MemMx.memcpy((byte *)hBmpScan0, (byte *)memPtr.Ptr, actualImage.Stride * actualImage.Height); memPtr.Dispose(); } //System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // hBmpScan0, rawBuffer.Length); }
public override MemBitmap LoadImage(Stream input) { using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(input)) { var bmpData2 = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); MemBitmap memBitmap = new MemBitmap(bmp.Width, bmp.Height); unsafe { byte *dst = (byte *)MemBitmap.GetBufferPtr(memBitmap).Ptr; MemMx.memcpy(dst, (byte *)bmpData2.Scan0, bmpData2.Stride * bmpData2.Height); } return(memBitmap); } }
public static MemBitmap CopyImgBuffer(this MemBitmap src, int srcX, int srcY, int srcW, int srcH) { //simple copy #if DEBUG Rectangle orgSourceRect = new Rectangle(0, 0, src.Width, src.Height); Rectangle requestRect = new Rectangle(srcX, srcY, srcW, srcH); #endif Rectangle toCopyRect = Rectangle.Intersect( new Rectangle(0, 0, src.Width, src.Height), //orgSourceRect new Rectangle(srcX, srcY, srcW, srcH)); //reqstRect if (toCopyRect.Width == 0 || toCopyRect.Height == 0) { return(null); } //----- MemBitmap copyBmp = new MemBitmap(toCopyRect.Width, toCopyRect.Height); unsafe { using (TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(src)) using (TempMemPtr dstBufferPtr = MemBitmap.GetBufferPtr(copyBmp)) { int *srcPtr = (int *)srcBufferPtr.Ptr; int *dstPtr = (int *)dstBufferPtr.Ptr; int lineEnd = srcY + srcH; int orgSrcW = src.Width; for (int line = toCopyRect.Top; line < toCopyRect.Bottom; ++line) { MemMx.memcpy((byte *)dstPtr, (byte *)(srcPtr + ((line * orgSrcW) + toCopyRect.Left)), toCopyRect.Width * 4); dstPtr += toCopyRect.Width; } } } return(copyBmp); }
static System.Drawing.Bitmap CreatePlatformBitmap(MemBitmap memBmp) { System.Drawing.Bitmap bmp = new System.Drawing.Bitmap( memBmp.Width, memBmp.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var srcPtr = MemBitmap.GetBufferPtr(memBmp); var bmpdata = bmp.LockBits( new System.Drawing.Rectangle(0, 0, memBmp.Width, memBmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb); unsafe { MemMx.memcpy( (byte *)bmpdata.Scan0, (byte *)srcPtr.Ptr, srcPtr.LengthInBytes); } bmp.UnlockBits(bmpdata); return(bmp); }
///////////////////////////////////////////////////////////////////////////////////// public static void CopyToGdiPlusBitmapSameSizeNotFlip( MemBitmap srcMemBmp, Bitmap dstBitmap) { //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 = dstBitmap.Height; int w = dstBitmap.Width; BitmapData bitmapData1 = dstBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadWrite, dstBitmap.PixelFormat); IntPtr scan0 = bitmapData1.Scan0; int stride = bitmapData1.Stride; //byte[] srcBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(srcMemBmp); unsafe { //fixed (byte* bufferH = &srcBuffer[0]) byte *srcBufferH = (byte *)srcBufferPtr.Ptr; { byte *target = (byte *)scan0; int startRowAt = 0; for (int y = 0; y < h; ++y) { //byte* src = bufferH + ((y - 1) * stride); byte *src = srcBufferH + startRowAt; //System.Runtime.InteropServices.Marshal.Copy( // srcBuffer,//src // startRowAt, // (IntPtr)target, // stride); MemMx.memcpy(target, src, stride); startRowAt += stride; target += stride; } } } srcBufferPtr.Dispose(); dstBitmap.UnlockBits(bitmapData1); //} //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 static void CopyFromGdiPlusBitmapSameSizeTo32BitsBuffer( Bitmap windowsBitmap, MemBitmap actualImage) { int h = windowsBitmap.Height; int w = windowsBitmap.Width; //byte[] targetBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr targetBufferPtr = MemBitmap.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); MemMx.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.Dispose(); windowsBitmap.UnlockBits(bitmapData1); }