GDI+映像扭曲變形

來源:互聯網
上載者:User

出來的效果是橢圓或圓形,呈渦狀,視原始圖片而定。

總體來說,這個代碼處理的速度很慢,如果使用不安全的程式碼的話,在效能上會有很大的提升。

 

        private void button1_Click(object sender, EventArgs e)
        {
            Bitmap image = new Bitmap(@"c:/DSC_0096_S.JPG");
            int x, y;
            float x1, y1;
            float fx, fy, xmid, ymid, ar;
            Bitmap image2 = new Bitmap(image);
            xmid = (float)(image.Width / 2.0);
            ymid = (float)(image.Height / 2.0);
            ar = (float)(image.Height) / (float)(image.Width);
            for (y = 0; y < image.Height; y++)
            {
                for (x = 0; x < image.Width; x++)
                {
                    ComputePixel(ar * (x - xmid), y - ymid, out fx, out fy);
                    x1 = xmid + fx / ar;
                    y1 = ymid + fy;
                    image2.SetPixel(x, y, GetPixelColorInterpolated(ref image, x1, y1));
                }
            }
            this.pictureBox1.Image = image2;
        }

        static int ComputePixel(float x, float y, out float x1, out float y1)
        {
            double r, nn;
            if (x == 0 && y == 0)
            {
                x1 = x;
                y1 = y;
                return 1;
            }
            nn = Math.Sqrt(x * x + y * y);
            r = (Math.Abs(x) > Math.Abs(y)) ? Math.Abs(nn / x) : Math.Abs(nn / y);
            x1 = (float)(r * x);
            y1 = (float)(r * y);
            return 1;
        }

        static Color GetPixelColorInterpolated(ref Bitmap image, float x, float y)
        {
            int xi = (int)(x);
            if (x < 0) xi--;
            int yi = (int)(y);
            if (y < 0) yi--;
            if (xi < -1 || xi >= image.Width || yi < -1 || yi >= image.Height)
            {
                return GetPixelColorWithOverflow(ref image, -999, -999);
            }
            //get four neighbouring pixels
            if ((xi + 1) < image.Width && xi >= 0 && (yi + 1) < image.Height && yi >= 0)
            {
                ushort wt1 = (ushort)((x - xi) * 256.0f), wt2 = (ushort)((y - yi) * 256.0f);
                ushort wd = (ushort)(wt1 * wt2 >> 8);
                ushort wb = (ushort)(wt1 - wd);
                ushort wc = (ushort)(wt2 - wd);
                ushort wa = (ushort)(256 - wt1 - wc);
                ushort wrr, wgg, wbb;
                Color clr = image.GetPixel(xi, yi);
                wbb = (ushort)(wa * clr.B);
                wgg = (ushort)(wa * clr.G);
                wrr = (ushort)(wa * clr.R);
                clr = image.GetPixel(xi + 1, yi);
                wbb += (ushort)(wb * clr.B);
                wgg += (ushort)(wb * clr.G);
                wrr += (ushort)(wb * clr.R);
                clr = image.GetPixel(xi, yi + 1);
                wbb += (ushort)(wc * clr.B);
                wgg += (ushort)(wc * clr.G);
                wrr += (ushort)(wc * clr.R);
                clr = image.GetPixel(xi + 1, yi + 1);
                wbb += (ushort)(wd * clr.B);
                wgg += (ushort)(wd * clr.G);
                wrr += (ushort)(wd * clr.R);
                return Color.FromArgb(255, wrr >> 8, wgg >> 8, wbb >> 8);
            }
            else
            {
                float t1 = x - xi, t2 = y - yi;
                float d = t1 * t2;
                float b = t1 - d;
                float c = t2 - d;
                float a = 1 - t1 - c;
                Color rgb11, rgb21, rgb12, rgb22;
                rgb11 = GetPixelColorWithOverflow(ref image, xi, yi);
                rgb21 = GetPixelColorWithOverflow(ref image, xi + 1, yi);
                rgb12 = GetPixelColorWithOverflow(ref image, xi, yi + 1);
                rgb22 = GetPixelColorWithOverflow(ref image, xi + 1, yi + 1);
                //calculate linear interpolation
                return Color.FromArgb(255,
                    (byte)(a * rgb11.R + b * rgb21.R + c * rgb12.R + d * rgb22.R),
                    (byte)(a * rgb11.G + b * rgb21.G + c * rgb12.G + d * rgb22.G),
                    (byte)(a * rgb11.B + b * rgb21.B + c * rgb12.B + d * rgb22.B));
            }
        }

        static Color GetPixelColorWithOverflow(ref Bitmap image, long x, long y)
        {
            if (!IsInside(ref image, x, y))
            {
                return Color.FromArgb(255, 255, 255, 255);
            }
            return image.GetPixel((int)x, (int)y);
        }

        static bool IsInside(ref Bitmap image, long x, long y)
        {
            return (0 <= y && y < image.Height && 0 <= x && x < image.Width);
        }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.