static void SeparateByChannel(MyColor[] myColors, byte[] rBuffer, byte[] gBuffer, byte[] bBuffer, byte[] aBuffer) { for (int i = 0; i < 16; ++i) { MyColor m = myColors[i]; rBuffer[i] = m.r; gBuffer[i] = m.g; bBuffer[i] = m.b; aBuffer[i] = m.a; } }
static MyColor GetApproximateColor_Bicubic(BufferReader4 reader, double cx, double cy) { //TODO: review here, //passing pointer to array or use stackalloc byte[] rBuffer = new byte[16]; byte[] gBuffer = new byte[16]; byte[] bBuffer = new byte[16]; byte[] aBuffer = new byte[16]; //nearest neighbor if (reader.CurrentX > 2 && reader.CurrentY > 2 && reader.CurrentX < reader.Width - 2 && reader.CurrentY < reader.Height - 2) { //read 4 point sample MyColor[] colors = new MyColor[16]; reader.SetStartPixel((int)cx, (int)cy); reader.Read16(colors); double x0 = (int)cx; double x1 = (int)(cx + 1); double xdiff = cx - x0; double y0 = (int)cy; double y1 = (int)(cy + 1); double ydiff = cy - y0; SeparateByChannel(colors, rBuffer, gBuffer, bBuffer, aBuffer); double result_B = myInterpolator.getValueBytes(bBuffer, xdiff, ydiff); double result_G = myInterpolator.getValueBytes(gBuffer, xdiff, ydiff); double result_R = myInterpolator.getValueBytes(rBuffer, xdiff, ydiff); double result_A = myInterpolator.getValueBytes(aBuffer, xdiff, ydiff); //clamp if (result_B > 255) { result_B = 255; } else if (result_B < 0) { result_B = 0; } if (result_G > 255) { result_G = 255; } else if (result_G < 0) { result_G = 0; } if (result_R > 255) { result_R = 255; } else if (result_R < 0) { result_R = 0; } if (result_A > 255) { result_A = 255; } else if (result_A < 0) { result_A = 0; } return(new MyColor((byte)result_R, (byte)result_G, (byte)result_B, (byte)result_A)); } else { return(reader.ReadOnePixel()); } }
unsafe 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; TempMemPtr bufferPtr = srcCB.GetBufferPtr(); byte * buffer = (byte *)bufferPtr.Ptr; 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(MyVectorHelper.NewFromTwoPoints(vertex[0], srcPt).CrossProduct(ab_vec)); dbc = Math.Abs(MyVectorHelper.NewFromTwoPoints(vertex[1], srcPt).CrossProduct(bc_vec)); dcd = Math.Abs(MyVectorHelper.NewFromTwoPoints(vertex[2], srcPt).CrossProduct(cd_vec)); dda = Math.Abs(MyVectorHelper.NewFromTwoPoints(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; } 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); }
static MyColor GetApproximateColor_Bicubic(BufferReader4 reader, double cx, double cy) { byte[] rBuffer = new byte[16]; byte[] gBuffer = new byte[16]; byte[] bBuffer = new byte[16]; byte[] aBuffer = new byte[16]; //nearest neighbor if (reader.CurrentX > 2 && reader.CurrentY > 2 && reader.CurrentX < reader.Width - 2 && reader.CurrentY < reader.Height - 2) { //read 4 point sample MyColor[] colors = new MyColor[16]; reader.SetStartPixel((int)cx, (int)cy); reader.Read16(colors); double x0 = (int)cx; double x1 = (int)(cx + 1); double xdiff = cx - x0; double y0 = (int)cy; double y1 = (int)(cy + 1); double ydiff = cy - y0; SeparateByChannel(colors, rBuffer, gBuffer, bBuffer, aBuffer); double result_B = myInterpolator.getValueBytes(bBuffer, xdiff, ydiff); double result_G = myInterpolator.getValueBytes(gBuffer, xdiff, ydiff); double result_R = myInterpolator.getValueBytes(rBuffer, xdiff, ydiff); double result_A = myInterpolator.getValueBytes(aBuffer, xdiff, ydiff); //clamp if (result_B > 255) { result_B = 255; } else if (result_B < 0) { result_B = 0; } if (result_G > 255) { result_G = 255; } else if (result_G < 0) { result_G = 0; } if (result_R > 255) { result_R = 255; } else if (result_R < 0) { result_R = 0; } if (result_A > 255) { result_A = 255; } else if (result_A < 0) { result_A = 0; } return new MyColor((byte)result_R, (byte)result_G, (byte)result_B, (byte)result_A); } else { return reader.ReadOnePixel(); } }
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; }