2012-12-17 7 views
10

Ich habe eine UIView die ich als UIImage speichern möchte. Ich mache das mit UIGraphicsBeginImageContext, und es funktioniert OK. Aber wenn ich Maske auf die Bilder in der (view/layer.mask) anwende, ist das Bild, das ich durch UIGraphicsBeginImageContext gefangen habe falsch (die Maskierung funktioniert, wenn die App ausgeführt wird, aber nicht beim Versuch, eine UIImage von einem UIView zu erhalten). Hat jemand ein ähnliches Problem festgestellt?Maske funktioniert nicht, wenn eine uiview zu einem uiimage

+0

Können Sie bitte etwas Code zeigen, was Sie bisher haben bieten? –

+0

Maskieren Sie die Quellen-UIView im Voraus, bevor Sie die UIImage davon erfassen? Oder maskieren Sie das resultierende UIImage in dem Moment, in dem Sie es in einem UIImageView anzeigen möchten? –

+0

Ich habe einen Beispielcode hinzugefügt. –

Antwort

5

Wenn ich richtig verstehe, möchten Sie eine UIImage von einer UIView-Ebene erstellen, während diese Ebene maskiert ist. Ich nehme an, dass das Ziel UIImage einen transparenten Hintergrund haben soll.

traf ich keine Probleme dieser Implementierung und ich habe ein Demo-Projekt, das Sie einen Blick auf nehmen:

https://bitbucket.org/reydan/so_imagemask

Als erstes müssen Sie die Maske drücken Taste. Es wird ein Maskenbild (schwarz und weiß) aus dem Bündel geladen und als Ebenenmaske für den obigen UIView-Container festgelegt.

Dann können Sie die Schaltfläche Kopieren Image drücken, die den UIView-Container in einen UIImage rendert, und dann auf die Zielbildansicht unten einstellen, um das Ergebnis zu sehen.

Ich werde auch die 2 Methoden hier posten:

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

Offenbar renderInContext: auf iOS6 nicht die Maske verwendet werden (wie es auch hier auf SO gesagt wird). Meine Lösung war, Maske manuell auf das Bild anzuwenden. Die Maske wird aus der mask -Eigenschaft der Ebene übernommen und in einem Kontext gerendert, so dass wir keine Probleme mit Transformationen/contentModes/etc haben. Hier

ist die aktualisierte Quellcode (es ist auch auf 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; 

} 

EDIT Überprüfen Sie bitte das neueste Projekt auf bitbucket wie es die neueste Version enthält.

+0

Das funktioniert nicht für mich. Ich komme immer noch in der UIIage in Quadrate. Ich benutze genau den gleichen Code wie du. Ich verstehe nicht??? Ihr Beispielprojekt arbeitet für mich. Kann es etwas mit iOS 7 SDK sein. Dein Projekt ist in iOS 7 und meins für iOS 6 erstellt. Kann das etwas anderes machen? –

+0

Ich werde versuchen und ios 6 verwenden und mit einer Antwort –

+0

zurückkommen Tatsächlich funktioniert es nicht auf ios 6.1 Ich habe das nicht erwartet. Ich werde sehen, wie ich das Projekt aktualisieren kann, damit es funktioniert. –

0

Hier ist ein Beispielcode, mit dem ich die UIView als UIImageView und das Maskierungsbild für die Anwendung erhalten habe.

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

Ich habe eine UIView zum Zwecke der Zeichnung also dafür verwendet worden,

Vergabe der UIView (gezogen Bereich) in 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; 
} 

Jetzt haben Sie eine UIImageView Darstellung der UIView.

Jetzt machen wir das mit dem Maskeneffekt.

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