public bool rotate_stretch(double strx, double stry, Stretching kind, double angle, out Bitmap ans) { if (angle > MathWork.pi() * 2 || angle < 0) { if (output != null) { output.Dispose(); } output = null; ans = null; return(false); } try { laststrx = strx; laststry = stry; int diagonal = CalculateDiagonal(origin.Size, strx, stry); Size anssize = CalculateSize(origin.Size, strx, stry, angle, diagonal); int rkind = 0; int basement = 0; double xend = 0, yend = 0; if (angle < MathWork.pi() / 2) { rkind = 1; MathWork.rotate(diagonal, diagonal, diagonal, diagonal + origin.Height * stry, angle, ref xend, ref yend); basement = MathWork.round(xend); } else if (angle < MathWork.pi()) { rkind = 2; MathWork.rotate(diagonal, diagonal, diagonal, diagonal + origin.Height * stry, angle, ref xend, ref yend); basement = MathWork.round(yend); } else if (angle < MathWork.pi() * 3 / 2) { rkind = 3; MathWork.rotate(diagonal, diagonal, diagonal + origin.Width * strx, diagonal, angle, ref xend, ref yend); basement = MathWork.round(xend); } else { rkind = 4; MathWork.rotate(diagonal, diagonal, diagonal + origin.Width * strx, diagonal, angle, ref xend, ref yend); basement = MathWork.round(yend); } if (output != null) { output.Dispose(); } output = new Bitmap(anssize.Width, anssize.Height); pb.Maximum = anssize.Height; oupb = new PointBitmap(output); oupb.LockBits(); #region ComputeEveryPixel double u, v, temp; int ansr = 0, ansg = 0, ansb = 0; int oldxint = 0, oldyint = 0; int oriyint = 0, orixint = 0; double Sup1 = 1, Sup0 = 1, Sus1 = 1, Sus2 = 1, Svp1 = 1, Svp0 = 2, Svs1 = 3, Svs2 = 1; double kk1r = 1, kk2r = 1, kk3r = 1, kk4r = 1, kk1g = 1, kk2g = 2, kk3g = 3, kk4g = 2, kk1b = 3, kk2b = 2, kk3b = 1, kk4b = 2; Color a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, a41, a42, a43, a44; #region init a11 to a44 a11 = Color.Empty; a12 = Color.Empty; a13 = Color.Empty; a14 = Color.Empty; a21 = Color.Empty; a22 = Color.Empty; a23 = Color.Empty; a24 = Color.Empty; a31 = Color.Empty; a32 = Color.Empty; a33 = Color.Empty; a34 = Color.Empty; a41 = Color.Empty; a42 = Color.Empty; a43 = Color.Empty; a44 = Color.Empty; ExtraGetPixelRef(0, 0, ref a11); ExtraGetPixelRef(0, 0, ref a12); ExtraGetPixelRef(1, 0, ref a13); ExtraGetPixelRef(2, 0, ref a14); ExtraGetPixelRef(0, 0, ref a21); ExtraGetPixelRef(0, 0, ref a22); ExtraGetPixelRef(1, 0, ref a23); ExtraGetPixelRef(2, 0, ref a24); ExtraGetPixelRef(0, 1, ref a31); ExtraGetPixelRef(0, 1, ref a32); ExtraGetPixelRef(1, 1, ref a33); ExtraGetPixelRef(2, 1, ref a34); ExtraGetPixelRef(0, 2, ref a41); ExtraGetPixelRef(0, 2, ref a42); ExtraGetPixelRef(1, 2, ref a43); ExtraGetPixelRef(2, 2, ref a44); #endregion Color x_y, x_1_y, x_y_1, x_1_y_1; #region init x_y to x_1_y_1 x_y = ExtraGetPixel(0, 0); x_1_y = ExtraGetPixel(1, 0); x_y_1 = ExtraGetPixel(0, 1); x_1_y_1 = ExtraGetPixel(1, 1); #endregion int i, j; for (i = 0; i < anssize.Height; i++) { pb.PerformStep(); for (j = 0; j < anssize.Width; j++) { Point now = new Point(); if (rkind == 1) { now.X = basement + j; now.Y = anssize.Height - i + diagonal; //now.Y = diagonal + i; } else if (rkind == 2) { now.X = j + diagonal - anssize.Width; now.Y = basement + anssize.Height - i; //now.Y = basement + i; } else if (rkind == 3) { now.X = basement + j; now.Y = diagonal - i; //now.Y = i + diagonal - origin.Height; } else { now.X = diagonal + j; now.Y = basement + anssize.Height - i; //now.Y = basement + i; } PointF orip = ReachOrigin(now, strx, stry, angle, diagonal); if (orip == BlackPoint) { oupb.SetPixel(j, i, Color.Black); //oldxint = orixint; continue; } oriyint = MathWork.floor(orip.Y); orixint = MathWork.floor(orip.X); v = orip.Y - oriyint; u = orip.X - orixint; #region switch switch (kind) { case Stretching.Nearest: oupb.SetPixel(j, i, ExtraGetPixel(orixint, oriyint)); break; case Stretching.Bilinear: if (oldxint != orixint || oldyint != oriyint) { x_y = ExtraGetPixel(orixint, oriyint); x_1_y = ExtraGetPixel(orixint + 1, oriyint); x_y_1 = ExtraGetPixel(orixint, oriyint + 1); x_1_y_1 = ExtraGetPixel(orixint + 1, oriyint + 1); } temp = x_y.R + u * (x_1_y.R - x_y.R); ansr = MathWork.upcolor(MathWork.round(temp + v * (x_y_1.R - temp + u * (x_1_y_1.R - x_y_1.R)))); temp = x_y.G + u * (x_1_y.G - x_y.G); ansg = MathWork.upcolor(MathWork.round(temp + v * (x_y_1.G - temp + u * (x_1_y_1.G - x_y_1.G)))); temp = x_y.B + u * (x_1_y.B - x_y.B); ansb = MathWork.upcolor(MathWork.round(temp + v * (x_y_1.B - temp + u * (x_1_y_1.B - x_y_1.B)))); oupb.SetPixel(j, i, Color.FromArgb(ansr, ansg, ansb)); break; case Stretching.Bicubic: Sup1 = MathWork.KernelFunS(u + 1); Sup0 = MathWork.KernelFunS(u + 0); Sus1 = MathWork.KernelFunS(u - 1); Sus2 = MathWork.KernelFunS(u - 2); Svp1 = MathWork.KernelFunS(v + 1); Svp0 = MathWork.KernelFunS(v + 0); Svs1 = MathWork.KernelFunS(v - 1); Svs2 = MathWork.KernelFunS(v - 2); if (oldxint != orixint || oldyint != oriyint) { ExtraGetPixelRef(orixint - 1, oriyint - 1, ref a11); ExtraGetPixelRef(orixint - 0, oriyint - 1, ref a12); ExtraGetPixelRef(orixint + 1, oriyint - 1, ref a13); ExtraGetPixelRef(orixint + 2, oriyint - 1, ref a14); ExtraGetPixelRef(orixint - 1, oriyint - 0, ref a21); ExtraGetPixelRef(orixint - 0, oriyint - 0, ref a22); ExtraGetPixelRef(orixint + 1, oriyint - 0, ref a23); ExtraGetPixelRef(orixint + 2, oriyint - 0, ref a24); ExtraGetPixelRef(orixint - 1, oriyint + 1, ref a31); ExtraGetPixelRef(orixint - 0, oriyint + 1, ref a32); ExtraGetPixelRef(orixint + 1, oriyint + 1, ref a33); ExtraGetPixelRef(orixint + 2, oriyint + 1, ref a34); ExtraGetPixelRef(orixint - 1, oriyint + 2, ref a41); ExtraGetPixelRef(orixint - 0, oriyint + 2, ref a42); ExtraGetPixelRef(orixint + 1, oriyint + 2, ref a43); ExtraGetPixelRef(orixint + 2, oriyint + 2, ref a44); } kk1r = Sup1 * a11.R + Sup0 * a12.R + Sus1 * a13.R + Sus2 * a14.R; kk2r = Sup1 * a21.R + Sup0 * a22.R + Sus1 * a23.R + Sus2 * a24.R; kk3r = Sup1 * a31.R + Sup0 * a32.R + Sus1 * a33.R + Sus2 * a34.R; kk4r = Sup1 * a41.R + Sup0 * a42.R + Sus1 * a43.R + Sus2 * a44.R; kk1g = Sup1 * a11.G + Sup0 * a12.G + Sus1 * a13.G + Sus2 * a14.G; kk2g = Sup1 * a21.G + Sup0 * a22.G + Sus1 * a23.G + Sus2 * a24.G; kk3g = Sup1 * a31.G + Sup0 * a32.G + Sus1 * a33.G + Sus2 * a34.G; kk4g = Sup1 * a41.G + Sup0 * a42.G + Sus1 * a43.G + Sus2 * a44.G; kk1b = Sup1 * a11.B + Sup0 * a12.B + Sus1 * a13.B + Sus2 * a14.B; kk2b = Sup1 * a21.B + Sup0 * a22.B + Sus1 * a23.B + Sus2 * a24.B; kk3b = Sup1 * a31.B + Sup0 * a32.B + Sus1 * a33.B + Sus2 * a34.B; kk4b = Sup1 * a41.B + Sup0 * a42.B + Sus1 * a43.B + Sus2 * a44.B; ansr = MathWork.upcolor(MathWork.round(Svp1 * kk1r + Svp0 * kk2r + Svs1 * kk3r + Svs2 * kk4r)); ansg = MathWork.upcolor(MathWork.round(Svp1 * kk1g + Svp0 * kk2g + Svs1 * kk3g + Svs2 * kk4g)); ansb = MathWork.upcolor(MathWork.round(Svp1 * kk1b + Svp0 * kk2b + Svs1 * kk3b + Svs2 * kk4b)); oupb.SetPixel(j, i, Color.FromArgb(ansr, ansg, ansb)); break; } #endregion oldxint = orixint; } oldyint = oriyint; #if MYDEBUG DebugLogger.LogTimeStamp(); #endif } #endregion oupb.UnlockBits(); ans = output; pb.Value = 0; return(true); } catch (Exception e) { ans = null; return(false); } }
private void insert_Click(object sender, EventArgs e) { double strx, stry, angle = 0; try { strx = Double.Parse(textBox1.Text); stry = Double.Parse(textBox2.Text); if (checkBox1.Checked) { if (radioButton1.Checked) { angle = Double.Parse(textBox3.Text) * MathWork.pi() / 180; } else { angle = Double.Parse(textBox3.Text); } } if (MathWork.abs(angle) < 0.000001D) { if ((string)comboBox1.SelectedItem == "最近邻插值") { pictran.stretchpicture(strx, stry, Pictransformer.Stretching.Nearest, out output); } else if ((string)comboBox1.SelectedItem == "双线性插值") { pictran.stretchpicture(strx, stry, Pictransformer.Stretching.Bilinear, out output); } else if ((string)comboBox1.SelectedItem == "双三次插值") { pictran.stretchpicture(strx, stry, Pictransformer.Stretching.Bicubic, out output); } } else { if ((string)comboBox1.SelectedItem == "最近邻插值") { pictran.rotate_stretch(strx, stry, Pictransformer.Stretching.Nearest, angle, out output); } else if ((string)comboBox1.SelectedItem == "双线性插值") { pictran.rotate_stretch(strx, stry, Pictransformer.Stretching.Bilinear, angle, out output); } else if ((string)comboBox1.SelectedItem == "双三次插值") { pictran.rotate_stretch(strx, stry, Pictransformer.Stretching.Bicubic, angle, out output); } if (checkBox2.Checked) { pictran.crop(out output); } } if (output == null) { throw new Exception(); } pictureBox1.Image = White; if (MathWork.max(output.Width, output.Height) > MAXWH) { double resized = (double)MAXWH / MathWork.max(output.Width, output.Height); MessageBox.Show("图像太大,将以" + MathWork.round(100 * resized).ToString() + "%的比例缩放显示图片。若想查看图片全貌,请保存图片。"); Bitmap bpt = new Bitmap(MAXWH, MAXWH); Pictransformer ptmp = new Pictransformer(); ptmp.start(output, progressBar1); ptmp.stretchpicture(resized, resized, Pictransformer.Stretching.Nearest, out bpt); pictureBox1.Image = bpt; ptmp.stop2(); } else { pictureBox1.Image = output; } save.Enabled = true; } catch (Exception es) { MessageBox.Show("参数错误!(角度请小于360°,大于0°)"); save.Enabled = false; return; } }