2012-12-17 196 views
10

我有一個UIView,我想將它保存爲UIImage。我使用UIGraphicsBeginImageContext這樣做,它工作正常。但是,當我將遮罩應用於(view/layer.mask)中的圖像時,通過UIGraphicsBeginImageContext捕獲的圖像是錯誤的(遮罩在運行應用程序時正在工作,但在嘗試從UIView獲取UIImage時不起作用)。任何人遇到類似的問題將屏幕截圖捕捉到屏幕上時不起作用

+0

能否請您提供展示你有什麼到目前爲止一些代碼? –

+0

你是否在從它捕獲UIImage之前掩蓋了源UIView?或者當你試圖在UIImageView中顯示它時,你是否掩蓋了由此產生的UIImage? –

+0

我添加了一些示例代碼。 –

回答

5

如果我理解正確,您希望從UIView圖層創建UIImage,而該圖層被遮罩。我假設你想讓目標UIImage具有透明背景。

我遇到的這個實施沒有問題,我中有你可以看看演示項目:

https://bitbucket.org/reydan/so_imagemask

首先,您需要按面膜按鈕。它將從該包中加載一個蒙版圖像(黑白),並將其設置爲上述UIView容器的圖層蒙版。

然後,您可以按下將UIView容器呈現爲UIImage的按鈕,然後將其設置爲下面的目標圖像視圖以查看結果。

我還會在這裏發表的2種方法:

- (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)。 我的解決方案是手動將遮罩應用於圖像。蒙版取自圖層的蒙板屬性並在上下文中渲染,所以我們沒有任何轉換/ contentModes /等的問題。

下面是更新的源代碼(它也可在到位桶):

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

} 

編輯 請檢查到位桶的最新項目,因爲它包含了最新版本。

+0

這對我不起作用。我仍然在UIImage中得到UIView的平方。我使用與您完全相同的代碼。我不明白???您的示例項目爲我工作。它可以是iOS 7 SDK的東西嗎?你的項目是建立在iOS 7和我的iOS 6.我可以做出任何不同? –

+0

我會嘗試使用ios 6並回答一個答案 –

+0

事實上,它不適用於ios 6.1我沒有想到這一點。我會如何更新該項目以使其工作。 –

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