public Vector(PointF pt) { _x = pt.X; _y = pt.Y; }
public Vector(PointF st, PointF end) { _x = end.X - st.X; _y = end.Y - st.Y; }
ActualImage GetTransformedBilinearInterpolation() { //4 points sampling //weight between four point ActualImage destCB = new ActualImage(rect.Width, rect.Height, PixelFormat.ARGB32); MyImageReaderWriter destWriter = new MyImageReaderWriter(); destWriter.ReloadImage(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; var ab_vec = this.AB; var bc_vec = this.BC; var cd_vec = this.CD; var 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(new Vector(vertex[0], srcPt).CrossProduct(ab_vec)); dbc = Math.Abs(new Vector(vertex[1], srcPt).CrossProduct(bc_vec)); dcd = Math.Abs(new Vector(vertex[2], srcPt).CrossProduct(cd_vec)); dda = Math.Abs(new Vector(vertex[3], 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 - (float)x1; if (dx1 < 0) dx1 = 0; dx1 = 1f - dx1; dx2 = 1f - dx1; dy1 = ptInPlane.Y - (float)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)); //destCB.SetColorPixel(x, y, new ColorRGBA((byte)b, (byte)g, (byte)r, (byte)a)); } } } return destCB; }
ActualImage 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 rectWidth = rect.Width; int rectHeight = rect.Height; var ab_vec = this.AB; var bc_vec = this.BC; var cd_vec = this.CD; var da_vec = this.DA; byte[] buffer = srcCB.GetBuffer(); int stride = srcCB.Stride; int bmpWidth = srcCB.Width; int bmpHeight = srcCB.Height; BufferReader4 reader = new BufferReader4(buffer, stride, bmpWidth, bmpHeight); MyColor[] pixelBuffer = new MyColor[16]; byte[] sqPixs = new byte[16]; //Bitmap outputbmp = new Bitmap(rectWidth, rectHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); ////----------------------------------------------- //var bmpdata2 = outputbmp.LockBits(new Rectangle(0, 0, rectWidth, rectHeight), // System.Drawing.Imaging.ImageLockMode.ReadWrite, outputbmp.PixelFormat); ////----------------------------------------- ActualImage destCB = new ActualImage(rect.Width, rect.Height, PixelFormat.ARGB32); MyImageReaderWriter destWriter = new MyImageReaderWriter(); destWriter.ReloadImage(destCB); //PointF ptInPlane = new PointF(); //int stride2 = bmpdata2.Stride; //byte[] outputBuffer = new byte[stride2 * outputbmp.Height]; // int targetPixelIndex = 0; // int startLine = 0; 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(new Vector(vertex[0], srcPt).CrossProduct(ab_vec)); dbc = Math.Abs(new Vector(vertex[1], srcPt).CrossProduct(bc_vec)); dcd = Math.Abs(new Vector(vertex[2], srcPt).CrossProduct(cd_vec)); dda = Math.Abs(new Vector(vertex[3], 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 - 2 && y1 >= 2 && y1 < srcH - 2) { reader.SetStartPixel(x1, y1); reader.Read16(pixelBuffer); //do interpolate //find src pixel and approximate MyColor color = GetApproximateColor_Bicubic(reader, ptInPlane.X, ptInPlane.Y); //outputBuffer[targetPixelIndex] = (byte)color.b; //outputBuffer[targetPixelIndex + 1] = (byte)color.g; //outputBuffer[targetPixelIndex + 2] = (byte)color.r; //outputBuffer[targetPixelIndex + 3] = (byte)color.a; //targetPixelIndex += 4; destWriter.SetPixel(x, y, new Drawing.Color(color.a, color.b, color.g, color.r)); //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("d:\\WImageTest\\n_lion_bicubic.png"); //return outputbmp; return destCB; }
ActualImage GetTransformedBitmapNoInterpolation() { var destCB = new ActualImage(rect.Width, rect.Height, PixelFormat.ARGB32); var destWriter = new MyImageReaderWriter(); destWriter.ReloadImage(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; var ab_vec = this.AB; var bc_vec = this.BC; var cd_vec = this.CD; var 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; } x1 = (int)ptInPlane.X; y1 = (int)ptInPlane.Y; destWriter.SetPixel(x, y, srcCB.GetPixel(x1, y1)); //------------------------------------- dab = Math.Abs((new Vector(vertex[0], srcPt)).CrossProduct(ab_vec)); dbc = Math.Abs((new Vector(vertex[1], srcPt)).CrossProduct(bc_vec)); dcd = Math.Abs((new Vector(vertex[2], srcPt)).CrossProduct(cd_vec)); dda = Math.Abs((new Vector(vertex[3], srcPt)).CrossProduct(da_vec)); ptInPlane.X = (float)(srcW * (dda / (dda + dbc))); ptInPlane.Y = (float)(srcH * (dab / (dab + dcd))); } } return destCB; }
private bool IsOnPlaneABCD(PointF pt) // including point on border { if (!Vector.IsCCW(pt, vertex[0], vertex[1])) { if (!Vector.IsCCW(pt, vertex[1], vertex[2])) { if (!Vector.IsCCW(pt, vertex[2], vertex[3])) { if (Vector.IsCCW(pt, vertex[3], vertex[0])) return true; } } } return false; }
public static double DistancePointLine(PointF pt, PointF lnA, PointF lnB) { Vector v1 = new Vector(lnA, lnB); Vector v2 = new Vector(lnA, pt); v1 /= v1.Magnitude; return Math.Abs(v2.CrossProduct(v1)); }
public static bool IsCCW(PointF pt1, PointF pt2, PointF pt3) { Vector V21 = new Vector(pt2, pt1); Vector v23 = new Vector(pt2, pt3); return V21.CrossProduct(v23) > 0; // sin(angle pt2 pt1 pt3) < 0, 180<angle pt2 pt1 pt3 <360 }
public static bool IsClockwise(PointF pt1, PointF pt2, PointF pt3) { Vector V21 = new Vector(pt2, pt1); Vector v23 = new Vector(pt2, pt3); return V21.CrossProduct(v23) < 0; // sin(angle pt1 pt2 pt3) > 0, 0<angle pt1 pt2 pt3 <180 }