iphone - snippet - title-tag




Wie bekomme ich ein gedrehtes, gezoomtes und geschwenktes Bild von einem UIImageView in voller Auflösung? (2)

Ich habe eine UIImageView, die mit Gestenerkennern gedreht, geschwenkt und skaliert werden kann. Als Ergebnis ist es in seiner umschließenden Ansicht beschnitten . Alles funktioniert gut, aber ich weiß nicht, wie ich den sichtbaren Teil des Bildes in voller Auflösung speichern kann. Es ist kein Screenshot.

Ich weiß, dass ich das UIImage direkt aus dem sichtbaren Inhalt des UIImageView bekomme, aber es ist auf die Auflösung des Bildschirms beschränkt.

Ich nehme an, dass ich die gleichen Transformationen auf dem UIImage machen muss und es beschneiden muss. Gibt es einen einfachen Weg das zu tun?

Update : Zum Beispiel habe ich eine UIImageView mit einem Bild in hoher Auflösung, sagen wir ein 8MP iPhone 4s Kamera Foto, das mit Gesten umgewandelt wird, so dass es skaliert wird, gedreht und bewegt sich in seiner einschließenden Ansicht. Offensichtlich gibt es einige Beschneidungen, so dass nur ein Teil des Bildes angezeigt wird. Es gibt einen großen Unterschied zwischen der angezeigten Bildschirmauflösung und der Unterstreichungsauflösung, ich brauche ein Bild in der Bildauflösung. Die UIImageView ist in UIViewContentModeScaleAspectFit , aber eine Lösung mit UIViewContentModeScaleAspectFill ist auch in Ordnung.

Das ist mein Code:

- (void)rotatePiece:(UIRotationGestureRecognizer *)gestureRecognizer {

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        [gestureRecognizer view].transform = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);
        [gestureRecognizer setRotation:0];
    }
}

- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer {

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        [gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]);
        [gestureRecognizer setScale:1];
    }
}

-(void)panGestureMoveAround:(UIPanGestureRecognizer *)gestureRecognizer;
{
    UIView *piece = [gestureRecognizer view];

    //We pass in the gesture to a method that will help us align our touches so that the pan and pinch will seems to originate between the fingers instead of other points or center point of the UIView    
    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {

        CGPoint translation = [gestureRecognizer translationInView:[piece superview]];
        [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y+translation.y)];
        [gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];
    } else if([gestureRecognizer state] == UIGestureRecognizerStateEnded) {
        //Put the code that you may want to execute when the UIView became larger than certain value or just to reset them back to their original transform scale
    }
}


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    // if the gesture recognizers are on different views, don't allow simultaneous recognition
    if (gestureRecognizer.view != otherGestureRecognizer.view)
        return NO;

    // if either of the gesture recognizers is the long press, don't allow simultaneous recognition
    if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]])
        return NO;

    return YES;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];    
    faceImageView.image = appDelegate.faceImage;

    UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotatePiece:)];
    [faceImageView addGestureRecognizer:rotationGesture];
    [rotationGesture setDelegate:self];

    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scalePiece:)];
    [pinchGesture setDelegate:self];
    [faceImageView addGestureRecognizer:pinchGesture];

    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureMoveAround:)];
    [panRecognizer setMinimumNumberOfTouches:1];
    [panRecognizer setMaximumNumberOfTouches:2];
    [panRecognizer setDelegate:self];
    [faceImageView addGestureRecognizer:panRecognizer];


    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

    [appDelegate fadeObject:moveIcons StartAlpha:0 FinishAlpha:1 Duration:2];
    currentTimer = [NSTimer timerWithTimeInterval:4.0f target:self selector:@selector(fadeoutMoveicons) userInfo:nil repeats:NO];

    [[NSRunLoop mainRunLoop] addTimer: currentTimer forMode: NSDefaultRunLoopMode];

}

Ich denke, Bellow Code erfassen Ihre aktuelle Ansicht ...

- (UIImage *)captureView {

    CGRect rect = [self.view bounds];

    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [self.yourImage.layer renderInContext:context];   
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return img;

}

Ich denke du willst den Bildschirm speichern und benutzen, also poste ich diesen Code ... Hoffe, das hilft dir ... :)


Der folgende Code erstellt einen Snapshot der umschließenden Ansicht (Superview von faceImageView mit clipsToBounds auf YES ) unter Verwendung eines berechneten Skalierungsfaktors.

Es setzt voraus, dass der Inhaltsmodus von faceImageView UIViewContentModeScaleAspectFit ist und dass der Rahmen von faceImageView auf die Grenzen des umschließendenViews festgelegt ist.

- (UIImage *)captureView {

    float imageScale = sqrtf(powf(faceImageView.transform.a, 2.f) + powf(faceImageView.transform.c, 2.f));    
    CGFloat widthScale = faceImageView.bounds.size.width / faceImageView.image.size.width;
    CGFloat heightScale = faceImageView.bounds.size.height / faceImageView.image.size.height;
    float contentScale = MIN(widthScale, heightScale);
    float effectiveScale = imageScale * contentScale;

    CGSize captureSize = CGSizeMake(enclosingView.bounds.size.width / effectiveScale, enclosingView.bounds.size.height / effectiveScale);

    NSLog(@"effectiveScale = %0.2f, captureSize = %@", effectiveScale, NSStringFromCGSize(captureSize));

    UIGraphicsBeginImageContextWithOptions(captureSize, YES, 0.0);        
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextScaleCTM(context, 1/effectiveScale, 1/effectiveScale);
    [enclosingView.layer renderInContext:context];   
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return img;
}

Abhängig von der aktuellen Transformation wird das resultierende Bild eine andere Größe haben. Wenn Sie beispielsweise vergrößern, wird die Größe kleiner. Sie können effectiveScale auf einen konstanten Wert setzen, um ein Bild mit einer konstanten Größe zu erhalten.

Ihr Gestenerkenner-Code begrenzt den Skalierungsfaktor nicht, dh Sie können ohne Einschränkung vergrößern / verkleinern. Das kann sehr gefährlich sein! Meine Aufnahmemethode kann wirklich große Bilder ausgeben, wenn Sie sehr stark herausgezoomt haben.

Wenn Sie herausgezoomt haben, wird der Hintergrund des aufgenommenen Bildes schwarz sein. Wenn Sie möchten, dass es transparent ist, müssen Sie den UIGraphicsBeginImageContextWithOptions von UIGraphicsBeginImageContextWithOptions auf NO .