12

我有一个UIView我想保存为UIImage. 我使用 来执行此操作UIGraphicsBeginImageContext,并且可以正常工作。但是,当我将蒙版应用于 (view/layer.mask) 中的图像时,我捕获的图像UIGraphicsBeginImageContext是错误的(在运行应用程序时蒙版有效,但在尝试UIImage从 a获取 a 时无效UIView)。有人遇到过类似的问题吗?

4

2 回答 2

5

如果我理解正确,您希望从 UIView 层创建一个 UIImage,而该层被屏蔽。我假设您希望目标 UIImage 具有透明背景。

我没有遇到任何问题,我有一个演示项目,你可以看看:

https://bitbucket.org/reydan/so_imagemask

您首先需要按下Mask按钮。它将从包中加载一个蒙版图像(黑白)并将其设置为上面 UIView 容器的图层蒙版。

然后,您可以按下将 UIView 容器渲染为 UIImage 的Copy Image按钮,然后将其设置为下面的目标图像视图以查看结果。

我还将在这里发布两种方法:

- (IBAction)onMask:(id)sender {

    UIImage* maskImage = [UIImage imageNamed:@"star.png"];
    UIImageView* maskImageView = [[UIImageView alloc] initWithImage:maskImage];
    maskImageView.contentMode = UIViewContentModeScaleAspectFit;
    maskImageView.frame = _mainContainerView.bounds;

    _mainContainerView.layer.mask = maskImageView.layer;
}

- (IBAction)onCopyImage:(id)sender {

    UIGraphicsBeginImageContextWithOptions(_mainContainerView.bounds.size, FALSE, [[UIScreen mainScreen] scale]);
    [_mainContainerView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    _destImageView.image = img;
}

编辑

显然renderInContext:在 IOS6 上不使用掩码(正如在 SO 上所说的那样)。我的解决方案是手动将蒙版应用于图像。蒙版取自图层的蒙版属性并在上下文中渲染,因此我们在转换/内容模式/等方面没有任何问题。

这是更新的源代码(也可以在 bitbucket 上找到):

- (IBAction)onCopyImage:(id)sender {

    // Get the image from the mainImageView
    UIGraphicsBeginImageContextWithOptions(_mainContainerView.bounds.size, FALSE, [[UIScreen mainScreen] scale]);
    [_mainContainerView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    // Use the next block if targeting IOS6
    {
        // Manually create a mask image (taken from the mask layer)
        UIGraphicsBeginImageContextWithOptions(_mainContainerView.bounds.size, TRUE, [[UIScreen mainScreen] scale]);

        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);
        CGContextFillRect(ctx, _mainContainerView.bounds);

        [_mainContainerView.layer.mask renderInContext:ctx];
        UIImage * maskimg = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();


        // Create a image mask from the UIImage
        CGImageRef maskRef = maskimg.CGImage;
        CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                            CGImageGetHeight(maskRef),
                                            CGImageGetBitsPerComponent(maskRef),
                                            CGImageGetBitsPerPixel(maskRef),
                                            CGImageGetBytesPerRow(maskRef),
                                            CGImageGetDataProvider(maskRef), NULL, false);

        // Apply the mask to our source image
        CGImageRef maskedimg= CGImageCreateWithMask(img.CGImage, mask);

        // Convert to UIImage so we can easily display it in a UIImageView
        img = [UIImage imageWithCGImage:maskedimg scale:img.scale orientation:img.imageOrientation];

        CGImageRelease(mask);
        CGImageRelease(maskedimg);
    }



    _destImageView.image = img;

}

编辑 请检查 bitbucket 上的最新项目,因为它包含最新版本。

于 2013-07-18T19:37:54.783 回答
0

这是一些示例代码,我用于将 UIView 作为 UIImageView 并为此应用蒙版图像。

 * UIView --> UIImageView --> With Mask images .

我一直使用 UIView 来绘图所以为此,

将 UIView(绘制区域)分配给 UIImageView 。

-(UIImage*) imageRepresentation
{
    [EAGLContext setCurrentContext:context];
    UIImageView* upsideDownImageView=[[UIImageView alloc] initWithImage: [self upsideDownImageRepresenation]];

    upsideDownImageView.transform=CGAffineTransformScale(upsideDownImageView.transform, 1, -1);

    UIView* container=[[UIView alloc] initWithFrame:upsideDownImageView.frame];
    [container addSubview:upsideDownImageView];
    UIImage* toReturn=nil;

    UIGraphicsBeginImageContext(container.frame.size);

    [container.layer renderInContext:UIGraphicsGetCurrentContext()];

    toReturn = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //[upsideDownImageView release];
    upsideDownImageView = nil;
    container = nil;
    //[container release];
    return toReturn;
}


-(UIImage*) upsideDownImageRepresenation
{
    int imageWidth = CGRectGetWidth([self bounds]);
    int imageHeight = CGRectGetHeight([self bounds]);

    //image buffer for export
    NSInteger myDataLength = imageWidth* imageHeight * 4;

    // allocate array and read pixels into it.
    GLubyte *tempImagebuffer = (GLubyte *) malloc(myDataLength);

    glReadPixels( 0, 0, imageWidth, imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, tempImagebuffer);

    // make data provider with data.
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, tempImagebuffer, myDataLength, ProviderReleaseData);

    // prep the ingredients
    int bitsPerComponent = 8;

   int bitsPerPixel = 32;
    int bytesPerRow = 4 * imageWidth;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;

    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    // make the cgimage
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    // then make the uiimage from that
    UIImage *myImage =  [UIImage imageWithCGImage:imageRef] ;

    CGDataProviderRelease(provider);
    CGImageRelease(imageRef);
    CGColorSpaceRelease(colorSpaceRef);

    return myImage;
}

现在您有了UIView 的 UIImageView 表示。

现在让我们用蒙版效果来制作它。

 UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); //imageView is wt we got by converting the UIIVew.
        [self.imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
// Add the mask Images even if want any UILabels etc ..
        [imageView.image drawInRect:CGRectMake(0, 0, 703, 315)];
        [maskImages.image drawAtPoint:CGPointMake(10, 10) blendMode:kCGBlendModeNormal alpha:0.2];
        [lblAckNo drawTextInRect:CGRectMake(320, 230,100,50)];

        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();// image with all of your effort.
        [[UIColor redColor] set];

         UIGraphicsEndImageContext();
于 2013-07-22T09:41:57.173 回答