Win2D
首发于Win2D
第三章(调整篇) 图像特效Effect

第三章(调整篇) 图像特效Effect

首先,在代码顶部添加命名空间
using Microsoft.Graphics.Canvas.Effects;

这篇文章讲述图像特效(Effect)的图像调整(Adjust),即对图像进行特效处理。


在展示效果之前,先准备一张位图

实例化位图(CanvasBitmap):

CanvasBitmap Bitmap;
Bitmap = await CanvasBitmap.LoadAsync(sender, "Assets/Minecraft.jpg");
一张简单的位图

灰度特效(GrayscaleEffect)

在画布控件的绘制事件里绘制灰度特效:

private void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
    //实例化灰度特效
    GrayscaleEffect effect = new GrayscaleEffect
    {
       Source = Bitmap,
    };
    //绘制特效
    CanvasDrawingSession ds = args.DrawingSession;
    ds.DrawImage(effect);
}
灰度特效(GrayscaleEffect)

反色特效(InvertEffect)

把上面的特效部分的代码改成:

//实例化反色特效
InvertEffect effect = new InvertEffect
{
   Source = Bitmap,
};
反色特效(InvertEffect)

曝光特效(ExposureEffect)

把上面的特效部分的代码改成:

//实例化曝光特效
ExposureEffect effect= new ExposureEffect
{
    Source = Bitmap,
    Exposure=1.2f, //Exposure曝光参数范围在-2.0f到2.0f之间
};
曝光特效(ExposureEffect) Exposure=1.2f
曝光特效(ExposureEffect) Exposure=-1.2f

饱和度特效(SaturationEffect)

把上面的特效部分的代码改成:

//实例化饱和度特效
SaturationEffect effect= new SaturationEffect
{
     Source = Bitmap,
     Saturation = 2.0f//Saturation饱和度参数的范围在0.0f到2.0f之间
};
饱和度特效(SaturationEffect) Saturation=2.0f
饱和度特效(SaturationEffect) Saturation=0.0f

色相旋转特效(HueRotationEffect)

//实例化色相旋转特效
HueRotationEffect effect= new HueRotationEffect
{
      Source = Bitmap,
      Angle = 2.0f//Angle角度参数的范围在0.0f到2π之间
};
色相旋转(HueRotationEffect) Angle=3.0f

对比度特效(ContrastEffect)

 //实例化对比度特效
ContrastEffect effect= new ContrastEffect
{
     Source = Bitmap,
      Contrast = 1.0f//Contrast对比度参数的范围在-1.0f到1.0f之间
};
对比度特效(ContrastEffect) Contrast=1.0f
对比度特效(ContrastEffect) Contrast=-1.0f

冷暖特效(TemperatureAndTintEffect)

//实例化冷暖特效
TemperatureAndTintEffect effect= new TemperatureAndTintEffect
{
   Source = Bitmap,
   Temperature = 1.0f, //Temperature温度参数的范围在-1.0f到1.0f之间
   Tint= 0.0f//Tint色彩增强参数的范围在-1.0f到1.0f之间
};
冷暖特效(TemperatureAndTintEffect ) Temperature = 1.0f 画面倾向于橙黄色
冷暖特效(TemperatureAndTintEffect ) Temperature = -1.0f 画面倾向于青蓝色
冷暖特效(TemperatureAndTintEffect ) Tint = 1.0f 画面倾向于青绿色
冷暖特效(TemperatureAndTintEffect ) Tint = -1.0f 画面倾向于紫红色

明度特效(BrightnessEffect)

把上面的特效部分的代码改成:

//实例化明度特效
BrightnessEffect effect= new BrightnessEffect
{
   Source = Bitmap,
   WhitePoint = new Vector2(1, 1),//白点控制图像的亮部
   BlackPoint  = new Vector2(0, 0),//黑点控制图像的暗部
};

请注意代码里面的WhitePoint (白点)和BlackPoint (黑点)

明度特效的参数并不同于普通的float等等在范围在一个线性区间的数值,而是Vector2向量。
Vector2 v=Vector2(X,Y);

WhitePoint (白点)

  • 白点控制图像的亮部
  • 白点的默认值是Vector2(1, 1)
  • 白点范围是Vector2(1, 1)到Vector2(0.5, 0.5)之间
  • 白点越靠近Vector2(0.5, 1),图像的亮部越亮
  • 白点越靠近Vector2(1, 0.5),图像的亮部越暗

BlackPoint (黑点)

  • 黑点控制图像的暗部
  • 黑点的默认值是Vector2(0, 0)
  • 黑点范围是Vector2(0, 0)到Vector2(0.5, 0.5)之间
  • 黑点越靠近Vector2(0.5, 0),图像的暗部越暗
  • 黑点越靠近Vector2(0, 0.5),图像的暗部越亮

默认:

明度特效(BrightnessEffect) WhitePoint = new Vector2(1, 1) BlackPoint = new Vector2(0, 0) 都处于默认值所以图像没有效果

亮部越亮,暗部越暗:

明度特效(BrightnessEffect) WhitePoint = new Vector2(0.5, 1) BlackPoint = new Vector2(0.5, 0) 亮部越亮,暗部越暗

亮部越暗,暗部越亮:

明度特效(BrightnessEffect) WhitePoint = new Vector2(1, 0.5) BlackPoint = new Vector2(0, 0.5) 亮部越暗,暗部越亮

亮部暗部同时亮:

明度特效(BrightnessEffect) WhitePoint = new Vector2(0.5, 1) BlackPoint = new Vector2(0, 0.5) 亮部暗部同时亮

亮部暗部同时暗:

明度特效(BrightnessEffect) WhitePoint = new Vector2(1, 0.5) BlackPoint = new Vector2(0.5, 0) 亮部暗部同时暗

如果你觉得同时写白点和黑点很复杂,只是想单纯的用一个线性参数比如float来代表明度(bright),来实现线性的调亮和调暗。简单你可以封装一下:

 float bright = 0.0f;//明度参数,范围在0.0f到2.0f之间

float WhiteX = Math.Min(2 - bright, 1);
float WhiteY = 1f;
float BlackX = Math.Max(1 - bright, 0);
float BlackY = 0f;

//实例化明度特效
BrightnessEffect effect = new BrightnessEffect
{
    Source = Bitmap,
    WhitePoint = new Vector2(WhiteX, WhiteY),//白点控制图像的亮部
    BlackPoint = new Vector2(BlackX, BlackY),//黑点控制图像的暗部
};

这样就可以在在0.0f到2.0f之间,调整明度(bright)的值来实现线性的调亮和调暗



高光&阴影特效(HighlightsAndShadowsEffect)

把上面的特效部分的代码改成:

 //实例化高光&阴影特效
HighlightsAndShadowsEffect effect = new HighlightsAndShadowsEffect
{
     Source = Bitmap,

     Highlights= 0.0f,//高光Highlights的范围 -1 to 1
     Shadows = 0.0f,//阴影Shadows的范围 -1 to 1

     Clarity = 0.0f,//清晰Clarity的范围 -1 to 1
     MaskBlurAmount = 1.25f,//模糊MaskBlurAmount的范围 0 to 10
};
高光&阴影特效(HighlightsAndShadowsEffect) Shadows=0.615f Highlight=-0.36f 图像的高光更亮,图像的阴影更暗,骚年自己感受一下吧我也说不清
高光&阴影特效(HighlightsAndShadowsEffect) Clarity=0.0f MaskBlurAmount=1.25f 我也不知道这两个参数有什么用,好像是平滑过渡什么的,都是玄学

注意

  1. 每个特效(Effect)的参数都是有范围的,比如曝光特效(ExposureEffect)的参数在-2到2之间,超过范围就会报错,建议封装一下并给数值加个if判断。
  2. 特效可以给图像带来各种效果,但是对于图像的计算并不是在特效实例化时计算的,而是在特效被绘制时计算的。因此想节省性能就要少写绘制方法。
  3. 特效是可以叠加的,你可以在画布控件的绘制事件里这样写:
 private void CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
        //实例化灰度特效
        GrayscaleEffect exposureEffect = new GrayscaleEffect
        {
            Source = Bitmap,//源为位图
        };
        //实例化反色特效
        InvertEffect invertEffect = new InvertEffect
        {
            Source = exposureEffect,//源为灰度特效
        };
        //绘制反色特效
        CanvasDrawingSession ds = args.DrawingSession;
        ds.DrawImage(invertEffect);
}


这样一张位图便在被灰度之后又被反色:

暂时到这里,下一篇继续讲......

文章被以下专栏收录

    Win2D是一款易于使用的Windows运行时API,可用于GPU加速的即时模式2D图形渲染。它适用于为Windows通用平台(UWP)编写应用程序的C#,C ++和VB开发人员。它利用了Direct2D的强大功能,并与XAML和CoreWindow无缝集成。