2012-12-17 3 views
10

UIView私はUIImageとして保存します。私はUIGraphicsBeginImageContextを使ってこれを行い、それは正常に動作します。しかし、(view/layer.mask)の画像にマスクを適用すると、UIGraphicsBeginImageContextでキャプチャした画像は間違っています(UIViewからUIImageを取得しようとしたときにマスクを適用していません)。誰もが同様の問題に遭遇しましたか?uiimageにuiviewをキャプチャするときにマスクが機能しません

+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; 
} 

EDIT

(それはまた、SOに、ここで言われたように)どうやらIOS6にrenderInContext:は、マスクを使用していません。 私の解決策は、手動で画像にマスクを適用することでした。マスクはレイヤのマスクプロパティから取得され、コンテキストでレンダリングされるため、transformations/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; 

} 

EDIT ビットバケットに最新のプロジェクトをご確認ください。

+0

これは私のためには機能しません。私はまだUIImageでUIViewの二乗を取得します。私はあなたとまったく同じコードを使用しています。分かりません???あなたのサンプルプロジェクトは私のために働いています。それはiOS 7 SDKで何かになることができますか?あなたのプロジェクトはiOS 7でビルドされ、iOS 6で開発されます。 –

+0

私は6を試してみて、答えを返す。 –

+0

実際、それはios 6.1ではうまくいきません。私はこれを期待していませんでした。私はそれが働くようにプロジェクトをどのように更新することができますか。 –

0

私はUIImageViewとしてUIViewを取得し、そのためのマスクイメージを適用するために使用されているサンプルコードです。

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

私は

はUIImageViewにUIViewの(描かれた領域)を割り当て、そのためのドローイングので、目的のためのUIViewを使用されています。

-(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(); 
関連する問題