Imagem principal no Xamarin.iOS

Core Image é uma nova estrutura introduzida com o iOS 5 para fornecer processamento de imagem e funcionalidade de aprimoramento de vídeo ao vivo. Este artigo apresenta esses recursos com exemplos do Xamarin.iOS.

Core Image é uma nova estrutura introduzida no iOS 5 que fornece uma série de filtros e efeitos integrados para aplicar a imagens e vídeos, incluindo detecção de rosto.

Este documento contém exemplos simples de:

  • Detecção de rosto.
  • Aplicando filtros a uma imagem
  • Listando os filtros disponíveis.

Esses exemplos devem ajudá-lo a começar a incorporar os recursos Core Image em seus aplicativos Xamarin.iOS.

Requisitos

Você deve usar a versão mais recente do Xcode.

Detecção Facial

O recurso de detecção de rosto Core Image faz exatamente o que diz – tenta identificar rostos em uma foto e retorna as coordenadas de quaisquer rostos que reconheça. Essas informações podem ser usadas para contar o número de pessoas em uma imagem, desenhar indicadores na imagem (por exemplo, para 'marcar' pessoas em uma fotografia), ou qualquer outra coisa que você possa pensar.

Este código de CoreImage\SampleCode.cs demonstra como criar e usar a detecção de rosto em uma imagem incorporada:

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);

A matriz de recursos será preenchida com CIFaceFeature objetos (se alguma face for detectada). Há um CIFaceFeature para cada rosto. CIFaceFeature tem as propriedades a seguir:

  • HasMouthPosition – Se uma boca foi detectada para este rosto.
  • HasLeftEyePosition – Se o olho esquerdo foi detectado para este rosto.
  • HasRightEyePosition – Se o olho direito foi detectado para este rosto.
  • MouthPosition – As coordenadas da boca para este rosto.
  • LeftEyePosition – As coordenadas do olho esquerdo para este rosto.
  • RightEyePosition – As coordenadas do olho direito para este rosto.

As coordenadas para todas essas propriedades têm sua origem no canto inferior esquerdo – ao contrário do UIKit, que usa o canto superior esquerdo como origem. Ao usar as coordenadas, CIFaceFeature certifique-se de 'invertê-las'. Esta exibição de imagem personalizada muito básica em CoreImage\CoreImageViewController.cs demonstra como desenhar triângulos 'indicador de face' na imagem (observe o FlipForBottomOrigin método):

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);
    }
}

Em seguida, no arquivo SampleCode.cs, a imagem e os recursos são atribuídos antes que a imagem seja redesenhada:

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

A captura de tela mostra a saída de exemplo: os locais dos recursos faciais detectados são exibidos em um UITextView e desenhados na imagem de origem usando CoreGraphics.

Por causa da maneira como o reconhecimento facial funciona, ele ocasionalmente detecta coisas além de rostos humanos (como esses macacos de brinquedo!).

Filtros

Existem mais de 50 filtros internos diferentes, e a estrutura é extensível para que novos filtros possam ser implementados.

Usando filtros

A aplicação de um filtro a uma imagem tem quatro etapas distintas: carregar a imagem, criar o filtro, aplicar o filtro e salvar (ou exibir) o resultado.

Primeiro, carregue uma imagem em um CIImage objeto.

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

Em segundo lugar, crie a classe de filtro e defina suas propriedades.

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

Em terceiro lugar, acesse a OutputImage propriedade e chame o CreateCGImage método para renderizar o resultado final.

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

Finalmente, atribua a imagem a uma exibição para ver o resultado. Em um aplicativo do mundo real, a imagem resultante pode ser salva no sistema de arquivos, no Álbum de Fotos, em um Tweet ou em um e-mail.

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

Essas capturas de tela mostram o resultado dos filtros e CIHueAdjust que são demonstrados no código de CISepia exemplo CoreImage.zip.

Consulte a Receita de ajuste de contrato e brilho de uma imagem para obter um exemplo do CIColorControls filtro.

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;

Listando filtros e suas propriedades

Esse código de CoreImage\SampleCode.cs gera a lista completa de filtros internos e seus parâmetros.

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";
   }
}

A Referência de Classe CIFilter descreve os 50 filtros internos e suas propriedades. Usando o código acima, você pode consultar as classes de filtro, incluindo valores padrão para parâmetros e os valores máximo e mínimo permitidos (que podem ser usados para validar entradas antes de aplicar um filtro).

A saída List Categories tem esta aparência no simulador – você pode rolar pela lista para ver todos os filtros e seus parâmetros.

A saída List Categories tem esta aparência no simulador

Cada filtro listado foi exposto como uma classe no Xamarin.iOS, portanto, você também pode explorar a API Xamarin.iOS.CoreImage no Navegador de Assembly ou usando o preenchimento automático no Visual Studio para Mac ou no Visual Studio.

Resumo

Este artigo mostrou como usar alguns dos novos recursos da estrutura de imagem principal do iOS 5, como detecção de rosto e aplicação de filtros a uma imagem. Existem dezenas de filtros de imagem diferentes disponíveis na estrutura para você usar.