Xamarin.iOS 中的 Core Image

Core Image 是 iOS 5 中引入的一个新框架,用于提供图像处理和实时视频增强功能。 本文通过 Xamarin.iOS 示例演示了这些功能。

Core Image 是 iOS 5 中引入的新框架,它提供许多可应用于图像和视频得内置筛选器和效果,包括人脸检测。

本文档包含以下简单示例:

  • 人脸检测。
  • 对图像应用滤镜
  • 列出可用的滤镜。

这些示例可帮助你开始将 Core Image 功能合并到 Xamarin.iOS 应用程序中。

要求

必须使用最新版本的 Xcode。

人脸检测

顾名思义,Core Image 人脸检测功能会尝试识别照片中的人脸,并返回识别到的任何人脸的坐标。 此信息可用于统计图像中的人数、在图像上绘制指示符(例如,用于“标记”照片中的人物)或你能想到的任何其他内容。

CoreImage\SampleCode.cs 中的代码演示了如何在嵌入图像上创建和使用人脸检测:

var image = new UIImage("photoFace.JPG");
var context = CIContext.FromOptions(null);
var detector = CIDetector.CreateFaceDetector (context, true);
var ciImage = CIImage.FromCGImage(image.CGImage);
CIFeature[] features = detector.FeaturesInImage(ciImage);

特征数组中将填充 CIFaceFeature 对象(如果检测到任何人脸)。 每个人脸都有一个 CIFaceFeatureCIFaceFeature 具有以下属性:

  • HasMouthPosition – 是否检测到此人脸的嘴。
  • HasLeftEyePosition – 是否检测到此人脸的左眼。
  • HasRightEyePosition – 是否检测到此人脸的右眼。
  • MouthPosition – 此人脸的嘴的坐标。
  • LeftEyePosition – 此人脸的左眼的坐标。
  • RightEyePosition – 此人脸的右眼的坐标。

所有这些属性的坐标都以左下角为原点 – 与使用左上角作为原点的 UIKit 不同。 使用 CIFaceFeature 上的坐标时,请务必“翻转”它们。 CoreImage\CoreImageViewController.cs 中这个非常简单的自定义图像视图演示了如何在图像上绘制“人脸指示符”三角形(请注意 FlipForBottomOrigin 方法):

public class FaceDetectImageView : UIView
{
    public Xamarin.iOS.CoreImage.CIFeature[] Features;
    public UIImage Image;
    public FaceDetectImageView (RectangleF rect) : base(rect) {}
    CGPath path;
    public override void Draw (RectangleF rect) {
        base.Draw (rect);
        if (Image != null)
            Image.Draw(rect);

        using (var context = UIGraphics.GetCurrentContext()) {
            context.SetLineWidth(4);
            UIColor.Red.SetStroke ();
            UIColor.Clear.SetFill ();
            if (Features != null) {
                foreach (var feature in Features) { // for each face
                    var facefeature = (CIFaceFeature)feature;
                    path = new CGPath ();
                    path.AddLines(new PointF[]{ // assumes all 3 features found
                        FlipForBottomOrigin(facefeature.LeftEyePosition, 200),
                        FlipForBottomOrigin(facefeature.RightEyePosition, 200),
                        FlipForBottomOrigin(facefeature.MouthPosition, 200)
                    });
                    path.CloseSubpath();
                    context.AddPath(path);
                    context.DrawPath(CGPathDrawingMode.FillStroke);
                }
            }
        }
    }
    /// <summary>
    /// Face recognition coordinates have their origin in the bottom-left
    /// but we are drawing with the origin in the top-left, so "flip" the point
    /// </summary>
    PointF FlipForBottomOrigin (PointF point, int height)
    {
        return new PointF(point.X, height - point.Y);
    }
}

然后在 SampleCode.cs 文件中,在重新绘制图像之前分配图像和特征:

faceView.Image = image;
faceView.Features = features;
faceView.SetNeedsDisplay();

屏幕截图显示了示例输出:检测到的人脸特征的位置显示在 UITextView 中,并使用 CoreGraphics 绘制到源图像上。

由于人脸识别的工作方式,偶尔会检测到人脸以外的东西(例如这些玩具猴!)。

筛选器

有超过 50 种不同的内置滤镜,并且该框架是可缩放的,以便可以实现新的滤镜。

使用筛选器

将滤镜应用于图像需要执行四个不同的步骤:加载图像、创建滤镜、应用滤镜和保存(或显示)结果。

首先,将图像加载到 CIImage 对象中。

var uiimage = UIImage.FromFile ("photo.JPG");
var ciimage = new CIImage (uiimage);

其次,创建滤镜类并设置其属性。

var sepia = new CISepiaTone();
sepia.Image = ciimage;
sepia.Intensity = 0.8f;

第三,访问 OutputImage 属性并调用 CreateCGImage 方法来呈现最终结果。

CIImage output = sepia.OutputImage;
var context = CIContext.FromOptions(null);
var cgimage = context.CreateCGImage (output, output.Extent);

最后,将图像分配到视图以查看结果。 在实际应用程序中,生成的图像可能会保存到文件系统、相册、推文或电子邮件中。

var ui = UIImage.FromImage (cgimage);
imgview.Image = ui;

这些屏幕截图显示了 CoreImage.zip 示例代码中演示的 CISepiaCIHueAdjust 滤镜的结果。

有关 滤镜的示例,请参阅调整图像方案的对比度和亮度CIColorControls

var uiimage = UIImage.FromFile("photo.JPG");
var ciimage = new CIImage(uiimage);
var hueAdjust = new CIHueAdjust();   // first filter
hueAdjust.Image = ciimage;
hueAdjust.Angle = 2.094f;
var sepia = new CISepiaTone();       // second filter
sepia.Image = hueAdjust.OutputImage; // output from last filter, input to this one
sepia.Intensity = 0.3f;
CIFilter color = new CIColorControls() { // third filter
    Saturation = 2,
    Brightness = 1,
    Contrast = 3,
    Image = sepia.OutputImage    // output from last filter, input to this one
};
var output = color.OutputImage;
var context = CIContext.FromOptions(null);
// ONLY when CreateCGImage is called do all the effects get rendered
var cgimage = context.CreateCGImage (output, output.Extent);
var ui = UIImage.FromImage (cgimage);
imgview.Image = ui;
var context = CIContext.FromOptions (null);
var context = CIContext.FromOptions(new CIContextOptions() {
    UseSoftwareRenderer = true  // CPU
});
var cgimage = context.CreateCGImage (output, output.Extent);
var ui = UIImage.FromImage (cgimage);
imgview.Image = ui;

列出滤镜及其属性

CoreImage\SampleCode.cs 中的此代码输出内置滤镜及其参数的完整列表。

var filters = CIFilter.FilterNamesInCategories(new string[0]);
foreach (var filter in filters){
   display.Text += filter +"\n";
   var f = CIFilter.FromName (filter);
   foreach (var key in f.InputKeys){
     var attributes = (NSDictionary)f.Attributes[new NSString(key)];
     var attributeClass = attributes[new NSString("CIAttributeClass")];
     display.Text += "   " + key;
     display.Text += "   " + attributeClass + "\n";
   }
}

CIFilter 类参考介绍了 50 个内置滤镜及其属性。 使用上面的代码可以查询滤镜类,包括参数的默认值以及最大和最小允许值(可用于在应用滤镜之前验证输入)。

“列出类别”输出在模拟器上看起来像这样 - 可以滚动列表以查看所有滤镜及其参数。

模拟器上的“列出类别”输出如下所示

列出的每个滤镜均已在 Xamarin.iOS 中公开为类,因此你还可以在程序集浏览器中浏览 Xamarin.iOS.CoreImage API,或者在 Visual Studio for Mac 或 Visual Studio 中使用自动完成功能。

总结

本文介绍了如何使用一些新的 iOS 5 Core Image 框架功能,例如人脸检测以及对图像应用滤镜。 该框架中有数十种不同的图像滤镜可供使用。