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 unsafe static TempMemPtr FromBmp(MemBitmap bmp, out byte *headPtr) { TempMemPtr ptr = MemBitmap.GetBufferPtr(bmp); headPtr = (byte *)ptr.Ptr; return(ptr); }
public unsafe static TempMemPtr FromBmp(IBitmapSrc actualBmp, out int *headPtr) { TempMemPtr ptr = actualBmp.GetBufferPtr(); headPtr = (int *)ptr.Ptr; return(ptr); }
public unsafe static TempMemPtr FromBmp(MemBitmap memBmp, out int *headPtr) { TempMemPtr ptr = MemBitmap.GetBufferPtr(memBmp); headPtr = (int *)ptr.Ptr; return(ptr); }
MemBitmap GetTransformedBitmapNoInterpolation() { var destCB = new MemBitmap(_destBounds.Width, _destBounds.Height); #if DEBUG destCB._dbugNote = "GetTransformedBitmapNoInterpolation()"; #endif var destWriter = new MyBitmapBlender(destCB); PointF ptInPlane = new PointF(); int x1, y1; double dab, dbc, dcd, dda; int rectWidth = _destBounds.Width; int rectHeight = _destBounds.Height; Vector ab_vec = _AB; Vector bc_vec = _BC; Vector cd_vec = _CD; Vector da_vec = _DA; int rectLeft = _destBounds.Left; int rectTop = _destBounds.Top; unsafe { using (TempMemPtr.FromBmp(_srcBmp, out int *bufferPtr)) { BufferReader4 reader = new BufferReader4(bufferPtr, _srcBmp.Width, _srcBmp.Height); 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; } x1 = (int)ptInPlane.X; y1 = (int)ptInPlane.Y; reader.SetStartPixel(x1, y1); destWriter.SetPixel(x, y, reader.Read1()); //------------------------------------- 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))); } } return(destCB); } } }
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 void dbugSaveToJpgFile(this MemBitmap bmp, string filename) { TempMemPtr tmpMem = MemBitmap.GetBufferPtr(bmp); SaveImgBufferToJpgFileUnsafe(tmpMem, bmp.Stride, bmp.Width, bmp.Height, filename); tmpMem.Dispose(); }
public static void SaveImgBufferToPngFile(TempMemPtr imgBuffer, int stride, int width, int height, string filename) { if (s_saveToFile != null) { unsafe { //fixed (int* head = imgBuffer.Ptr) int *head = (int *)imgBuffer.Ptr; { s_saveToFile((IntPtr)head, stride, width, height, filename); } } } }
/// <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 static unsafe void SaveImgBufferToJpgFileUnsafe( TempMemPtr tmpMem, int stride, int width, int height, string filename) { if (s_saveToFile != null) { unsafe { //fixed (int* head = &imgBuffer[0]) int *head = (int *)tmpMem.Ptr; { s_saveToFile((IntPtr)head, stride, width, height, filename); } } } }
public static void CopyFromGdiPlusBitmapSameSizeTo32BitsBuffer( Bitmap srcWindowsBitmap, MemBitmap dstMemBmp) { int h = srcWindowsBitmap.Height; int w = srcWindowsBitmap.Width; TempMemPtr targetBufferPtr = MemBitmap.GetBufferPtr(dstMemBmp); BitmapData bmpData = srcWindowsBitmap.LockBits( new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //read as 32 bits unsafe { PixelFarm.CpuBlit.NativeMemMx.MemCopy( (byte *)targetBufferPtr.Ptr, (byte *)bmpData.Scan0, bmpData.Stride * dstMemBmp.Height ); } srcWindowsBitmap.UnlockBits(bmpData); //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; // // } // // } // //} //} }
///////////////////////////////////////////////////////////////////////////////////// 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 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(); }
//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 MemBitmap 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 = _AB; Vector bc_vec = _BC; Vector cd_vec = _CD; Vector da_vec = _DA; using (TempMemPtr.FromBmp(_srcBmp, out int *bufferPtr)) { BufferReader4 reader = new BufferReader4(bufferPtr, _srcBmp.Width, _srcBmp.Height); MemBitmap destCB = new MemBitmap(_destBounds.Width, _destBounds.Height); #if DEBUG destCB._dbugNote = "GetTransformedBicubicInterpolation()"; #endif MyBitmapBlender destWriter = new MyBitmapBlender(destCB); int rectLeft = _destBounds.Left; int rectTop = _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; } //------------------------ //System.Runtime.InteropServices.Marshal.Copy( //outputBuffer, 0, //bmpdata2.Scan0, outputBuffer.Length); //outputbmp.UnlockBits(bmpdata2); ////outputbmp.Save("n_lion_bicubic.png"); //return outputbmp; return(destCB); } }
unsafe MemBitmap GetTransformedBilinearInterpolation() { //4 points sampling //weight between four point MemBitmap destCB = new MemBitmap(_destBounds.Width, _destBounds.Height); #if DEBUG destCB._dbugNote = "GetTransformedBilinearInterpolation()"; #endif 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 = _destBounds.Width; int rectHeight = _destBounds.Height; Vector ab_vec = _AB; Vector bc_vec = _BC; Vector cd_vec = _CD; Vector da_vec = _DA; int rectLeft = _destBounds.Left; int rectTop = _destBounds.Top; int srcW_lim = _srcW - 1; int srcH_lim = _srcH - 1; using (TempMemPtr.FromBmp(_srcBmp, out int *bufferPtr)) { BufferReader4 reader = new BufferReader4(bufferPtr, _srcBmp.Width, _srcBmp.Height); 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_lim && y1 >= 0 && y1 < srcH_lim) { //x2 = (x1 == srcW - 1) ? x1 : x1 + 1; //y2 = (y1 == srcH - 1) ? y1 : y1 + 1; x2 = x1 + 1; y2 = 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 reader.SetStartPixel(x1, y1); Drawing.Color x1y1Color; Drawing.Color x2y1Color; Drawing.Color x1y2Color; Drawing.Color x2y2Color; reader.Read4(out x1y1Color, out x2y1Color, out x1y2Color, out x2y2Color); //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.A * dx1y1) + (x2y1Color.A * dx2y1) + (x1y2Color.A * dx1y2) + (x2y2Color.A * dx2y2); float b = (x1y1Color.B * dx1y1) + (x2y1Color.B * dx2y1) + (x1y2Color.B * dx1y2) + (x2y2Color.B * dx2y2); float g = (x1y1Color.G * dx1y1) + (x2y1Color.G * dx2y1) + (x1y2Color.G * dx1y2) + (x2y2Color.G * dx2y2); float r = (x1y1Color.R * dx1y1) + (x2y1Color.R * dx2y1) + (x1y2Color.R * dx1y2) + (x2y2Color.R * dx2y2); destWriter.SetPixel(x, y, new Drawing.Color((byte)a, (byte)r, (byte)g, (byte)b)); } } } return(destCB); } }