滤镜之变形Distort特效

本文介绍了几种常见的视频扭曲特效,包括挤压、球面、漩涡及波浪等,并提供了具体的实现代码。通过数学变换来改变像素位置,创造出有趣的视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一些扭曲Distort特效也在滤镜中比较常见,而且如果在视频拍摄的时候使用则一般会比较有趣,如在Mac电脑上的PhotoBooth软件拍摄就有很多变形的Effect。这里介绍几种特效包括有:挤压(pinch)、球面特效(Spherize)、漩涡(Swirl)、波浪(Wave)等,这几个特效在PhotoSprite软件中都有代码。其他的一些变形也可以根据公式写出来,写出自己独特的一些变形特效出来。

这些特效都是对像素的位置进行改变,而不改变像素值,利用一些数学上的变换公式来进行。

原图:



l       挤压效果


代码:

 // 弧度、半径
        double radian, radius;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 当前点与图像中心点的偏移量
            offsetX = x - midX;
            offsetY = y - midY;

            // 弧度
            radian = Math.Atan2(offsetY, offsetX);

            // 半径
            radius = Math.Sqrt(offsetX * offsetX + offsetY * offsetY);
            radius = Math.Sqrt(radius) * degree;

            // 映射实际像素点
            X = (int)(radius * Math.Cos(radian)) + midX;
            Y = (int)(radius * Math.Sin(radian)) + midY;

            // 边界约束
            if (X < 0) X = 0;
            if (X >= width) X = width - 1;
            if (Y < 0) Y = 0;
            if (Y >= height) Y = height - 1;

            src = (byte*)srcScan0 + Y * stride + X * BPP;

            dst[3] = src[3]; // A
            dst[2] = src[2]; // R
            dst[1] = src[1]; // G
            dst[0] = src[0]; // B

            dst += BPP;
          } // x
          dst += offset;
        } // y
      }

l       球面效果


代码:
// 弧度、半径
        double radian, radius;
        int midX = width / 2;
        int midY = height / 2;
        // Max(midX, midY)
        double maxMidXY = (midX > midY ? midX : midY);
        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 当前点与图像中心点的偏移量
            offsetX = x - midX;
            offsetY = y - midY;

            // 弧度
            radian = Math.Atan2(offsetY, offsetX);

            // 注意,这里并非实际半径
            radius = (offsetX * offsetX + offsetY * offsetY) / maxMidXY;

            // 映射实际像素点
            X = (int)(radius * Math.Cos(radian)) + midX;
            Y = (int)(radius * Math.Sin(radian)) + midY;

            // 边界约束
            if (X < 0) X = 0;
            if (X >= width) X = width - 1;
            if (Y < 0) Y = 0;
            if (Y >= height) Y = height - 1;

            src = (byte*)srcScan0 + Y * stride + X * BPP;

            dst[3] = src[3]; // A
            dst[2] = src[2]; // R
            dst[1] = src[1]; // G
            dst[0] = src[0]; // B

            dst += BPP;
          } // x
          dst += offset;
        } // y
      }

l       漩涡效果


代码:

 // 弧度、半径
        double radian, radius;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 当前点与图像中心点的偏移量
            offsetX = x - midX;
            offsetY = y - midY;

            // 弧度
            radian = Math.Atan2(offsetY, offsetX);

            // 半径,即两点间的距离
            radius = Math.Sqrt(offsetX * offsetX + offsetY * offsetY);

            // 映射实际像素点
            X = (int)(radius * Math.Cos(radian + swirlDegree * radius)) + midX;
            Y = (int)(radius * Math.Sin(radian + swirlDegree * radius)) + midY;

            // 边界约束
            if (X < 0) X = 0;
            if (X >= width) X = width - 1;
            if (Y < 0) Y = 0;
            if (Y >= height) Y = height - 1;

            src = (byte*)srcScan0 + Y * stride + X * BPP;

            dst[3] = src[3]; // A
            dst[2] = src[2]; // R
            dst[1] = src[1]; // G
            dst[0] = src[0]; // B

            dst += BPP;
          } // x
          dst += offset;
        } // y
      }

l       波浪效果


代码:
double PI2 = Math.PI * 2.0;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            X = (int)(degree * Math.Sin(PI2 * y / 128.0)) + x;
            Y = (int)(degree * Math.Cos(PI2 * x / 128.0)) + y;

            // 边界约束
            if (X < 0) X = 0;
            if (X >= width) X = width - 1;
            if (Y < 0) Y = 0;
            if (Y >= height) Y = height - 1;

            src = (byte*)srcScan0 + Y * stride + X * BPP;

            dst[3] = src[3]; // A
            dst[2] = src[2]; // R
            dst[1] = src[1]; // G
            dst[0] = src[0]; // B

            dst += BPP;
          } // x
          dst += offset;
        } // y
      }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值