public void Sharpen(IBitmapSrc img, int radius) { unsafe { TempMemPtr bufferPtr = img.GetBufferPtr(); int[] output = new int[bufferPtr.LengthInBytes / 4]; //TODO: review here again fixed(int *outputPtr = &output[0]) { byte *srcBuffer = (byte *)bufferPtr.Ptr; int * srcBuffer1 = (int *)srcBuffer; int * outputBuffer1 = (int *)outputPtr; int stride = img.Stride; int w = img.Width; int h = img.Height; MemHolder srcMemHolder = new MemHolder((IntPtr)srcBuffer1, bufferPtr.LengthInBytes / 4);// Surface srcSurface = new Surface(stride, w, h, srcMemHolder); // MemHolder destMemHolder = new MemHolder((IntPtr)outputPtr, bufferPtr.LengthInBytes / 4); Surface destSurface = new Surface(stride, w, h, destMemHolder); // SharpenRenderer shRenderer1 = new SharpenRenderer(); shRenderer1.Amount = radius; shRenderer1.Render(srcSurface, destSurface, new PixelFarm.Drawing.Rectangle[] { new PixelFarm.Drawing.Rectangle(0, 0, w, h) }, 0, 1); } bufferPtr.Release(); //ActualImage.SaveImgBufferToPngFile(output, img.Stride, img.Width + 1, img.Height + 1, "d:\\WImageTest\\test_1.png"); img.ReplaceBuffer(output); } }
public static void CopyFromGdiPlusBitmapSameSize( Bitmap windowsBitmap, ActualBitmap 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 = ActualBitmap.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.Release(); ////////////////////////////////////////////////////////////////// //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( ActualBitmap actualImage, IntPtr hBmpScan0) { //1st, fast //byte[] rawBuffer = ActualImage.GetBuffer(actualImage); unsafe { TempMemPtr memPtr = ActualBitmap.GetBufferPtr(actualImage); MemMx.memcpy((byte *)hBmpScan0, (byte *)memPtr.Ptr, actualImage.Stride * actualImage.Height); memPtr.Release(); } //System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // hBmpScan0, rawBuffer.Length); }
public void Fill(IBitmapSrc bufferToFillOn, int x, int y) { y -= imageHeight; unchecked // this way we can overflow the uint on negative and get a big number { if ((uint)x >= bufferToFillOn.Width || (uint)y >= bufferToFillOn.Height) { return; } } _destImgRW = bufferToFillOn; TempMemPtr destBufferPtr = bufferToFillOn.GetBufferPtr(); unsafe { imageWidth = bufferToFillOn.Width; imageHeight = bufferToFillOn.Height; //reset new buffer, clear mem? pixelsChecked = new bool[imageWidth * imageHeight]; int *destBuffer = (int *)destBufferPtr.Ptr; int startColorBufferOffset = bufferToFillOn.GetBufferOffsetXY32(x, y); int start_color = *(destBuffer + startColorBufferOffset); fillRule.SetStartColor(Drawing.Color.FromArgb( (start_color >> 16) & 0xff, (start_color >> 8) & 0xff, (start_color) & 0xff)); LinearFill(destBuffer, x, y); while (ranges.Count > 0) { Range range = ranges.Dequeue(); int downY = range.y - 1; int upY = range.y + 1; int downPixelOffset = (imageWidth * (range.y - 1)) + range.startX; int upPixelOffset = (imageWidth * (range.y + 1)) + range.startX; for (int rangeX = range.startX; rangeX <= range.endX; rangeX++) { if (range.y > 0) { if (!pixelsChecked[downPixelOffset]) { int bufferOffset = bufferToFillOn.GetBufferOffsetXY32(rangeX, downY); if (fillRule.CheckPixel(*(destBuffer + bufferOffset))) { LinearFill(destBuffer, rangeX, downY); } } } if (range.y < (imageHeight - 1)) { if (!pixelsChecked[upPixelOffset]) { int bufferOffset = bufferToFillOn.GetBufferOffsetXY32(rangeX, upY); if (fillRule.CheckPixel(*(destBuffer + bufferOffset))) { LinearFill(destBuffer, rangeX, upY); } } } upPixelOffset++; downPixelOffset++; } } } destBufferPtr.Release(); }
public static void CopyFromGdiPlusBitmapSameSizeTo32BitsBuffer( Bitmap windowsBitmap, ActualBitmap actualImage) { int h = windowsBitmap.Height; int w = windowsBitmap.Width; //byte[] targetBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr targetBufferPtr = ActualBitmap.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.Release(); windowsBitmap.UnlockBits(bitmapData1); }
///////////////////////////////////////////////////////////////////////////////////// public static void CopyToGdiPlusBitmapSameSizeNotFlip( ActualBitmap actualImage, Bitmap bitmap) { //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 = 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[] srcBuffer = ActualImage.GetBuffer(actualImage); TempMemPtr srcBufferPtr = ActualBitmap.GetBufferPtr(actualImage); 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.Release(); bitmap.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; //} }
//ActualBitmap GetTransformedBilinearInterpolation() //{ // //4 points sampling // //weight between four point // ActualBitmap destCB = new ActualBitmap(rect.Width, rect.Height); // MyBitmapBlender destWriter = new MyBitmapBlender(destCB); // PointF ptInPlane = new PointF(); // int x1, x2, y1, y2; // double dab, dbc, dcd, dda; // float dx1, dx2, dy1, dy2, dx1y1, dx1y2, dx2y1, dx2y2; // int rectWidth = rect.Width; // int rectHeight = rect.Height; // Vector ab_vec = this.AB; // Vector bc_vec = this.BC; // Vector cd_vec = this.CD; // Vector da_vec = this.DA; // int rectLeft = this.rect.Left; // int rectTop = this.rect.Top; // for (int y = 0; y < rectHeight; ++y) // { // for (int x = 0; x < rectWidth; ++x) // { // PointF srcPt = new PointF(x, y); // srcPt.Offset(rectLeft, rectTop); // if (!IsOnPlaneABCD(srcPt)) // { // continue; // } // //------------------------------------- // dab = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p0, srcPt).CrossProduct(ab_vec)); // dbc = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p1, srcPt).CrossProduct(bc_vec)); // dcd = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p2, srcPt).CrossProduct(cd_vec)); // dda = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p3, srcPt).CrossProduct(da_vec)); // ptInPlane.X = (float)(srcW * (dda / (dda + dbc))); // ptInPlane.Y = (float)(srcH * (dab / (dab + dcd))); // x1 = (int)ptInPlane.X; // y1 = (int)ptInPlane.Y; // if (x1 >= 0 && x1 < srcW && y1 >= 0 && y1 < srcH) // { // //bilinear interpolation *** // x2 = (x1 == srcW - 1) ? x1 : x1 + 1; // y2 = (y1 == srcH - 1) ? y1 : y1 + 1; // dx1 = ptInPlane.X - x1; // if (dx1 < 0) dx1 = 0; // dx1 = 1f - dx1; // dx2 = 1f - dx1; // dy1 = ptInPlane.Y - y1; // if (dy1 < 0) dy1 = 0; // dy1 = 1f - dy1; // dy2 = 1f - dy1; // dx1y1 = dx1 * dy1; // dx1y2 = dx1 * dy2; // dx2y1 = dx2 * dy1; // dx2y2 = dx2 * dy2; // //use 4 points // Drawing.Color x1y1Color = srcCB.GetPixel(x1, y1); // Drawing.Color x2y1Color = srcCB.GetPixel(x2, y1); // Drawing.Color x1y2Color = srcCB.GetPixel(x1, y2); // Drawing.Color x2y2Color = srcCB.GetPixel(x2, y2); // float a = (x1y1Color.alpha * dx1y1) + (x2y1Color.alpha * dx2y1) + (x1y2Color.alpha * dx1y2) + (x2y2Color.alpha * dx2y2); // float b = (x1y1Color.blue * dx1y1) + (x2y1Color.blue * dx2y1) + (x1y2Color.blue * dx1y2) + (x2y2Color.blue * dx2y2); // float g = (x1y1Color.green * dx1y1) + (x2y1Color.green * dx2y1) + (x1y2Color.green * dx1y2) + (x2y2Color.green * dx2y2); // float r = (x1y1Color.red * dx1y1) + (x2y1Color.red * dx2y1) + (x1y2Color.red * dx1y2) + (x2y2Color.red * dx2y2); // destWriter.SetPixel(x, y, new Drawing.Color((byte)a, (byte)b, (byte)g, (byte)r)); // } // } // } // return destCB; //} unsafe ActualBitmap GetTransformedBicubicInterpolation() { //4 points sampling //weight between four point PointF ptInPlane = new PointF(); int x1, x2, y1, y2; double dab, dbc, dcd, dda; //float dx1, dx2, dy1, dy2, dx1y1, dx1y2, dx2y1, dx2y2; int destRectWidth = _destBounds.Width; int dectRectHeight = _destBounds.Height; Vector ab_vec = this.AB; Vector bc_vec = this.BC; Vector cd_vec = this.CD; Vector da_vec = this.DA; TempMemPtr bufferPtr = _srcBmp.GetBufferPtr(); BufferReader4 reader = new BufferReader4((int *)bufferPtr.Ptr, _srcBmp.Width, _srcBmp.Height); ActualBitmap destCB = new ActualBitmap(_destBounds.Width, _destBounds.Height); MyBitmapBlender destWriter = new MyBitmapBlender(destCB); int rectLeft = this._destBounds.Left; int rectTop = this._destBounds.Top; //*** PixelFarm.Drawing.Color[] colors = new PixelFarm.Drawing.Color[16]; int srcW_lim = srcW - 2; int srcH_lim = srcH - 2; for (int y = 0; y < dectRectHeight; ++y) { for (int x = 0; x < destRectWidth; ++x) { PointF srcPt = new PointF(x, y); srcPt.Offset(rectLeft, 0); if (!IsOnPlaneABCD(srcPt)) { continue; } //------------------------------------- dab = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p0, srcPt).CrossProduct(ab_vec)); dbc = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p1, srcPt).CrossProduct(bc_vec)); dcd = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p2, srcPt).CrossProduct(cd_vec)); dda = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p3, srcPt).CrossProduct(da_vec)); ptInPlane.X = (float)(srcW * (dda / (dda + dbc))); ptInPlane.Y = (float)(srcH * (dab / (dab + dcd))); x1 = (int)ptInPlane.X; y1 = (int)ptInPlane.Y; if (x1 >= 2 && x1 < srcW_lim && y1 >= 2 && y1 < srcH_lim) { reader.SetStartPixel(x1, y1); //reader.Read16(pixelBuffer); //do interpolate //find src pixel and approximate destWriter.SetPixel(x, y, GetApproximateColor_Bicubic(reader, colors, ptInPlane.X, ptInPlane.Y)); //TODO:review here blue switch to red channel } } //newline // startLine += stride2; //targetPixelIndex = startLine; } bufferPtr.Release(); //------------------------ //System.Runtime.InteropServices.Marshal.Copy( //outputBuffer, 0, //bmpdata2.Scan0, outputBuffer.Length); //outputbmp.UnlockBits(bmpdata2); ////outputbmp.Save("d:\\WImageTest\\n_lion_bicubic.png"); //return outputbmp; return(destCB); }