Xamarin iOS:如何逐个像素地改变UIImage的颜色

时间:2017-11-01 13:50:13

标签: xamarin xamarin.ios uiimage

很抱歉,如果已经在某个地方得到了解答,但我找不到它。

基本上,我收到一个QR码,其中代码本身是黑色,背景是白色(这是一个UIImage)。我想将白色背景的颜色更改为透明或自定义颜色,并将QRCode颜色从黑色更改为白色。 (在Xamarin iOS中)

我已经知道如何使用以下代码获取特定像素的颜色:

static UIColor GetPixelColor(CGBitmapContext context, byte[] rawData, 
UIImage barcode, CGPoint pt)
    {
        var handle = GCHandle.Alloc(rawData);
        UIColor resultColor = null;
        using (context)
        {
            context.DrawImage(new CGRect(-pt.X, pt.Y - barcode.Size.Height, 
            barcode.Size.Width, barcode.Size.Height), barcode.CGImage);
            float red = (rawData[0]) / 255.0f;
            float green = (rawData[1]) / 255.0f;
            float blue = (rawData[2]) / 255.0f;
            float alpha = (rawData[3]) / 255.0f;
            resultColor = UIColor.FromRGBA(red, green, blue, alpha);
        }

        return resultColor;
    }

这是我目前的职能:

    static UIImage GetRealQRCode(UIImage barcode)
    {
        int width = (int)barcode.Size.Width;
        int height = (int)barcode.Size.Height;
        var bytesPerPixel = 4;
        var bytesPerRow = bytesPerPixel * width;
        var bitsPerComponent = 8;
        var colorSpace = CGColorSpace.CreateDeviceRGB();
        var rawData = new byte[bytesPerRow * height];

        CGBitmapContext context = new CGBitmapContext(rawData, width, 
        height, bitsPerComponent, bytesPerRow, colorSpace, 
        CGImageAlphaInfo.PremultipliedLast);

        for (int i = 0; i < rawData.Length; i++)
        {
            for (int j = 0; j < bytesPerRow; j++)
            {
                CGPoint pt = new CGPoint(i, j);
                UIColor currentColor = GetPixelColor(context, rawData, 
                barcode, pt);
            }
        }
    }

任何人都知道如何做到这一点? 提前谢谢!

3 个答案:

答案 0 :(得分:3)

假设os_name = os_info.Name.encode('utf-8').split(b'|')[0] UIImage支持(而不是CGImage):

CIImage

enter image description here

答案 1 :(得分:2)

如果您实际上不需要访问单个像素但仅使用最终结果,使用CoreImage预先存在的过滤器,您可以先反转颜色,然后使用黑色像素作为alpha蒙版。否则,请使用Marshal.AllocHGlobal和指针查看我的其他答案。

using (var coreImage = new CIImage(ImageView1.Image))
using (var invertFilter = CIFilter.FromName("CIColorInvert"))
{
    invertFilter.Image = coreImage;
    using (var alphaMaskFiter = CIFilter.FromName("CIMaskToAlpha"))
    {
        alphaMaskFiter.Image = invertFilter.OutputImage;
        var newCoreImage = alphaMaskFiter.OutputImage;
        var uiimage = new UIImage(newCoreImage);

        imageView2.Image = uiimage; // Do something with your new UIImage
    }
}

优点是这是快速的;-)并且结果是相同的:

enter image description here

如果您需要更快的处理,假设您批量转换了大量这些图像,您可以编写一个自定义CIKernel,将这两个过滤器合并到一个内核中,因此只处理一次图像。

答案 2 :(得分:-1)

使用此方法的Xamarin.IOS可以将所有颜色白色转换为透明,仅适用于文件&#34; .jpg&#34;使用.png不起作用但您可以将文件转换为jpg并调用此方法。

 public static UIImage ProcessImage (UIImage image)
        { 
            CGImage rawImageRef = image.CGImage;
            nfloat[] colorMasking = new nfloat[6] { 222, 255, 222, 255, 222, 255 };
            CGImage imageRef = rawImageRef.WithMaskingColors(colorMasking);
            UIImage imageB = UIImage.FromImage(imageRef);
            return imageB;
        }

问候

MSDN documentation