예제 #1
0
        /// <summary>
        ///	比率 s,t を求める
        /// </summary>
        /// <param name="p">形状変形パラメータ</param>
        /// <param name="s">[out]比率(横方向)</param>
        /// <param name="t">[out]比率(縦方向)</param>
        /// <returns>true:範囲内, false:範囲外</returns>
        private static bool ResolveEqu(TfParam p, out double s, out double t)
        {
            s = -1.0;
            t = -1.0;

            double sa = -1.0;
            double ta = -1.0;
            double sb = -1.0;
            double tb = -1.0;

            double p1 = (p.a * p.h - p.f * p.c);
            double p2 = (p.d * p.f - p.c * p.g + p.b * p.h - p.a * p.e);
            double p3 = (p.d * p.g - p.b * p.e);
            double tm;

            if (p1 == 0.0)
            {
                s = (p.d / p.b);
                t = (p.b * p.e - p.d * p.g) / (p.b * p.h + p.d * p.f);
                //return true;
            }
            else if (Resolve2Equ(p1, p2, p3, out ta, out tb))
            {
                tm = (p.a * ta + p.b);
                if (tm != 0.0)
                {
                    sa = (p.d - p.c * ta) / tm;
                }

                tm = (p.a * tb + p.b);
                if (tm != 0.0)
                {
                    sb = (p.d - p.c * tb) / tm;
                }

                if ((0 <= sa && sa <= 1.0) && (0 <= ta && ta <= 1.0))
                {
                    s = sa;
                    t = ta;
                }
                else if ((0 <= sb && sb <= 1.0) && (0 <= tb && tb <= 1.0))
                {
                    s = sb;
                    t = tb;
                }
            }

            return(s != -1.0 && t != -1.0);
        }
예제 #2
0
        /// <summary>
        /// 変形処理
        /// </summary>
        /// <param name="srcImg">元画像</param>
        /// <param name="destImg">[out] 変形後画像</param>
        /// <param name="pt">変形後画像の頂点情報</param>
        /// <returns>true:成功, false:失敗</returns>
        public static bool Transform(Bitmap srcImg, out Bitmap destImg, List <Point> pt)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Reset();
            sw.Start();

            destImg = null;
            BitmapByte srcByte  = new BitmapByte();
            BitmapByte destByte = new BitmapByte();

            Color   pxCol = Color.FromArgb(0, 0, 0, 0);
            Color   bgCol = Color.FromArgb(0, 0, 0, 0);
            TfParam p = new TfParam();
            int     calcWidth, calcHeight;
            int     destWidth, destHeight;
            double  xa, ya, xb, yb, xc, yc, xd, yd;
            double  s, t;                   // 対象画素の元画像に対する比率 (0 <= s,t <=1)
            double  tx, ty;                 // 変形後の座標

            try
            {
                destWidth  = pt[0].X;
                destHeight = pt[0].Y;;
                for (int i = 1; i < pt.Count; i++)
                {
                    if (destWidth < pt[i].X)
                    {
                        destWidth = pt[i].X;
                    }
                    if (destHeight < pt[i].Y)
                    {
                        destHeight = pt[i].Y;
                    }
                }
                destWidth++;
                destHeight++;

                destImg = new Bitmap(destWidth, destHeight);
                destByte.LockBitmap(destImg, ImageLockMode.WriteOnly);

                srcByte.LockBitmap(srcImg, ImageLockMode.ReadOnly);
                calcWidth  = srcByte.Width - 1;
                calcHeight = srcByte.Height - 1;

                // 頂点データは反時計回りだが、パラメータには時計回りでセットする
                xa  = pt[0].X; ya = pt[0].Y;
                xb  = pt[3].X; yb = pt[3].Y;
                xc  = pt[2].X; yc = pt[2].Y;
                xd  = pt[1].X; yd = pt[1].Y;
                p.a = (xc - xd - xb + xa);
                p.b = (xb - xa);
                p.c = (xd - xa);
                p.f = (yc - yd - yb + ya);
                p.g = (yb - ya);
                p.h = (yd - ya);

                for (int y = 0; y < destHeight; y++)
                {
                    for (int x = 0; x < destWidth; x++)
                    {
                        p.d = (x - xa);
                        p.e = (y - ya);

                        if (ResolveEqu(p, out s, out t) == false)
                        {
                            SetPixelByte(destByte, x, y, bgCol);
                            continue;
                        }

                        //if ((0 <= s && s <= 1.0) && (0 <= t && t <= 1.0))
                        //{
                        tx = s * calcWidth;
                        ty = t * calcHeight;
                        //}

                        if (Interpolate(srcByte, tx, ty, ref pxCol))
                        {
                            SetPixelByte(destByte, x, y, pxCol);
                        }
                        else
                        {
                            SetPixelByte(destByte, x, y, bgCol);
                        }
                    }
                }

                destByte.MarshalCopy();
            }
            catch (Exception ex)
            {
                return(false);
            }
            finally
            {
                try
                {
                    if (srcByte != null)
                    {
                        srcByte.UnlockBitmap();
                    }
                }
                finally
                {
                    if (destByte != null)
                    {
                        destByte.UnlockBitmap();
                    }
                }

                sw.Stop();
                Console.WriteLine("Transform time: {0}", sw.ElapsedMilliseconds);
            }

            return(true);
        }