美文网首页编程开发
iOS中的图片遮罩处理

iOS中的图片遮罩处理

作者: cyhai | 来源:发表于2018-08-08 17:03 被阅读461次

    光影遮罩

    这里我分类深色与浅色遮罩,效果是什么样呢,可以看下面的图片,第一张是原图,后面是遮罩图。


    [图片上传中...(mask.png-77d2d6-1533714162606-0)] [图片上传中...(mask02.png-40df11-1533714186966-0)] mask02.png

    深色遮罩

    Simulator Screen Shot - iPhone SE - 2018-08-08 at 15.46.08.png

    浅色遮罩

    Simulator Screen Shot - iPhone SE - 2018-08-08 at 15.54.18.png

    关键代码

    +(UIImage *)creatImageWithMaskImage:(UIImage *)MaskImage andBackimage:(UIImage *)Backimage{
        
        CGRect rect;
        if (MaskImage.size.height>1000.0||MaskImage.size.width>1000.0)
        {
            rect = CGRectMake(0,
                              0,
                              MaskImage.size.width,
                              MaskImage.size.height);
        }else{
            rect = CGRectMake(0,
                              0,
                              MaskImage.size.width * 4.0,
                              MaskImage.size.height * 4.0);
        }
        CGImageRef imageRef = CGImageCreateWithImageInRect([Backimage CGImage], rect);
        UIImage *cutIMG = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
        //遮罩图
        CGImageRef maskImage = MaskImage.CGImage;
        //原图
        CGImageRef originImage = cutIMG.CGImage;
        CGContextRef mainViewContentContext;
        CGColorSpaceRef colorSpace;
        colorSpace = CGColorSpaceCreateDeviceRGB();
        // create a bitmap graphics context the size of the image
        mainViewContentContext = CGBitmapContextCreate (NULL,
                                                        rect.size.width,
                                                        rect.size.height,
                                                        8,
                                                        0,
                                                        colorSpace,
                                                        kCGImageAlphaPremultipliedLast);
        // free the rgb colorspace
        CGColorSpaceRelease(colorSpace);
        if (mainViewContentContext==NULL)
        {
    //        NSLog(@"error");
        }
        
        CGContextClipToMask(mainViewContentContext,
                            CGRectMake(0,
                                       0,
                                       rect.size.width,
                                       rect.size.height),
                            maskImage);
        
        CGContextDrawImage(mainViewContentContext,
                           CGRectMake(0,
                                      0,
                                      rect.size.width,
                                      rect.size.height),
                           originImage);
        
        
        CGContextSetAllowsAntialiasing(mainViewContentContext, true);//说是抗锯齿,但貌似没用
        CGContextSetShouldAntialias(mainViewContentContext, true);
        // Create CGImageRef of the main view bitmap content, and then
        // release that bitmap context
        CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
        
        CGContextRelease(mainViewContentContext);
        // convert the finished resized image to a UIImage
        UIImage *theImage = [UIImage imageWithCGImage:mainViewContentBitmapContext];
        // image is retained by the property setting above, so we can
        // release the original
        
        CGImageRelease(mainViewContentBitmapContext);
        return theImage;
        
    }
    
    

    首先处理新生的画图范围

    CGRect rect;
        if (MaskImage.size.height>1000.0||MaskImage.size.width>1000.0)
        {
            rect = CGRectMake(0,
                              0,
                              MaskImage.size.width,
                              MaskImage.size.height);
        }else{
            rect = CGRectMake(0,
                              0,
                              MaskImage.size.width * 4.0,
                              MaskImage.size.height * 4.0);
        }
    

    然后我们需要把原图和遮罩图转换为像素位图

    CGImageRef imageRef = CGImageCreateWithImageInRect([Backimage CGImage], rect);
        UIImage *cutIMG = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
        //遮罩图
        CGImageRef maskImage = MaskImage.CGImage;
        //原图
        CGImageRef originImage = cutIMG.CGImage;
    

    然后需要定义一个图形上下文与色彩空间

    CGImageRef originImage = cutIMG.CGImage;
        CGContextRef mainViewContentContext;
        CGColorSpaceRef colorSpace;
        colorSpace = CGColorSpaceCreateDeviceRGB();
        // create a bitmap graphics context the size of the image
        mainViewContentContext = CGBitmapContextCreate (NULL,
                                                        rect.size.width,
                                                        rect.size.height,
                                                        8,
                                                        0,
                                                        colorSpace,
                                                        kCGImageAlphaPremultipliedLast);
        // free the rgb colorspace
        CGColorSpaceRelease(colorSpace);
    

    接下来是把原图和遮罩图的像素位图画到画布上

    CGContextClipToMask(mainViewContentContext,
                            CGRectMake(0,
                                       0,
                                       rect.size.width,
                                       rect.size.height),
                            maskImage);
        
        CGContextDrawImage(mainViewContentContext,
                           CGRectMake(0,
                                      0,
                                      rect.size.width,
                                      rect.size.height),
                           originImage);
        
        
        CGContextSetAllowsAntialiasing(mainViewContentContext, true);//说是抗锯齿,但貌似没用
        CGContextSetShouldAntialias(mainViewContentContext, true);
        // Create CGImageRef of the main view bitmap content, and then
        // release that bitmap context
        CGImageRef mainViewContentBitmapContext = CGBitmapContextCreateImage(mainViewContentContext);
        
        CGContextRelease(mainViewContentContext);
    

    注意要手动去释放已创建的指针。
    最后是把合成后的像素位图转换为一般的图片

        UIImage *theImage = [UIImage imageWithCGImage:mainViewContentBitmapContext];
        CGImageRelease(mainViewContentBitmapContext);
    

    除此之外还有一种方式,也是官方文档提到的

    遮罩方法二

    关键代码

    +(UIImage *)creatImageWithBackimage:(UIImage *)Backimage andMaskImage:(UIImage *)MaskImage
    {
        CGImageRef maskImage = MaskImage.CGImage;
        //    CGImageRef bgimage  = BgImage.CGImage;
        CGImageRef  mask = CGImageMaskCreate(CGImageGetWidth(maskImage), CGImageGetHeight(maskImage), CGImageGetBitsPerComponent(maskImage),  CGImageGetBitsPerPixel(maskImage), CGImageGetBytesPerRow(maskImage), CGImageGetDataProvider(maskImage),NULL, false);
        
        CGImageRef imageWithAlpha = Backimage.CGImage;
        CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);
        UIImage * newimage = [UIImage imageWithCGImage:masked];
        //    CGImageRelease(maskImage);
        //    CGImageRelease(imageWithAlpha);
        CGImageRelease(masked);
        return newimage;
    }
    

    从这里看的出来,相对而言简短很多。
    这里使用到的关键是

    CGImageMaskCreate(size_t width, size_t height,size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGDataProviderRef provider, const CGFloat decode[], bool shouldInterpolate)
    
    sizt_t:是定义的一个可移植性的单位,在64位机器中为8字节,32位位4字节。
    width:图片宽度像素
    height:图片高度像素
    bitsPerComponent:每个颜色的比特数,例如在rgba-32模式下为8
    bitsPerPixel:每个像素的总比特数
    bytesPerRow:每一行占用的字节数,注意这里的单位是字节
    space:颜色空间模式,例如const CFStringRef kCGColorSpaceGenericRGB 这个函数可以返回一个颜色空间对象。
    bitmapInfo:位图像素布局,这是个枚举
    provider:数据源提供者
    decode[]:解码渲染数组
    shouldInterpolate:是否抗锯齿
    intent:图片相关参数
    

    后面设置遮罩图的透明通道

     CGImageRef imageWithAlpha = Backimage.CGImage;
        CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);
        UIImage * newimage = [UIImage imageWithCGImage:masked];
        //    CGImageRelease(maskImage);
        //    CGImageRelease(imageWithAlpha);
        CGImageRelease(masked);
    

    PS:第二种方法和第一种的效果是相反的。

    相关文章

      网友评论

        本文标题:iOS中的图片遮罩处理

        本文链接:https://www.haomeiwen.com/subject/affxbftx.html