使用MonoTouch创建自定义图像过滤器

时间:2014-01-03 19:44:51

标签: c# ios image-processing xamarin.ios xamarin

我正在使用Xamarin for iOS动态创建合成图像。我有两个图像,一个是基本图像(黑色和白色),另一个是彩色滤镜的alpha蒙版“贴图”。然后,在运行时,提供RGB值,这样我就可以使合成图像成为应有的颜色。

我找到了很多改变整个图像的解决方案,但我找不到一个好的解决方案来创建那个只对面具贴图中包含的区域(带有alpha值)着色的滤色器:

基本图片:

enter image description here enter image description here

产生的图像(如果我告诉它我想要红色):

enter image description here

在MonoDroid中,我能够创建自定义ImageView并覆盖OnDraw方法,然后使用ColorMatrixColorFilter,它像魅力一样工作,但不知道如何在MonoTouch中完成同样的事情。

这就是我为MonoDroid所做的:

    protected override void OnDraw(Canvas canvas)
    {
        if (_alphaMask == null)
            _alphaMask = BitmapFactory.DecodeResource(Resources, GetDrawable("star_mask"));

        if(_image == null)
            _image = BitmapFactory.DecodeResource(Resources, GetDrawable("star"));

        AdjustColor(_color, canvas, _alphaMask, _image);
    }

    private static void AdjustColor(Color color, Canvas c, Bitmap alphaMask, Bitmap image)
    {
        float R = color.R;
        float G = color.G;
        float B = color.B;
        var maskPaint = new Paint();
        var mat = new[]
        {
            0, 0, 0, 0, R, //red
            0, 0, 0, 0, G, //green
            0, 0, 0, 0, B, //blue
            0, 0, 0, 1, 0  //alpha
        };
        ColorMatrix cm = new ColorMatrix(mat);
        maskPaint.SetColorFilter(new ColorMatrixColorFilter(cm));
        c.DrawBitmap(image, 0, 0, null);
        c.DrawBitmap(alphaMask, 0, 0, maskPaint);
    }

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

好的......不是最优雅的解决方案,但我在彼此之上创建了两个ImageView

在基本图片的顶部是MaskView,然后使用以下方法创建彩色UIImage

private UIImage GetColoredImage(string imageName, Color color)
    {
        UIImage image = UIImage.FromBundle(imageName);

        UIGraphics.BeginImageContext(image.Size);
        CGContext context = UIGraphics.GetCurrentContext();

        context.TranslateCTM(0, image.Size.Height);
        context.ScaleCTM(1.0f, -1.0f);

        var rect = new RectangleF(0, 0, image.Size.Width, image.Size.Height);

        // draw image, (to get transparancy mask)
        context.SetBlendMode(CGBlendMode.Normal);
        context.DrawImage(rect, image.CGImage);

        // draw the color using the sourcein blend mode so its only draw on the non-transparent pixels
        context.SetBlendMode(CGBlendMode.SourceIn);
        context.SetFillColor(color.R / 255f, color.G / 255f, color.B / 255f, 1);
        context.FillRect(rect);

        UIImage coloredImage = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();
        return coloredImage;
    }

如果有人有更好的解决方案(可能使用CIFilter),我很乐意看到它。