2016-04-18 1 views
0

J'utilise CGImageCreateWithImageInRect dans Swift pour créer une copie d'une partie d'une image à l'emplacement tactile.CGImageCreateWithImageInRect tronquer

Mon code fonctionne très bien sauf lorsque l'utilisateur touche le bord de l'écran et que la taille rectale tombe en dehors du cadre de vue. Au lieu de retourner un carré, il renvoie un rectangle (je suppose) de couper la quantité qui se trouve en dehors de la vue. Le changement de forme rejette la position de l'image copiée, de sorte qu'il ne s'aligne pas sur l'image inférieure. Comment puis-je conserver la forme/taille carrée et ignorer les limites, donc mes images sont alignées?

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    let touch = touches.first!.locationInView(mainImageView?.superview) 

    UIGraphicsBeginImageContext(self.view.bounds.size) 
    UIApplication.sharedApplication().keyWindow!.layer.renderInContext(UIGraphicsGetCurrentContext()!) 
    let screenshot = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    let crop = CGRectMake(touch.x - CGFloat(brushWidth)/2, touch.y - CGFloat(brushWidth)/2, CGFloat(brushWidth), CGFloat(brushWidth)) 

    let imageRef = CGImageCreateWithImageInRect(screenshot.CGImage, crop) 

    if imageRef != nil { 
     let newImage: UIImage = UIImage(CGImage: imageRef!, scale: mainImageView.image!.scale, orientation: mainImageView.image!.imageOrientation) 

       let bgImage = UIImageView(image: processedImage) 
       bgImage.center = touch 
       self.view.addSubview(bgImage) 

      } 
     } 
    } 

} 

Voici un exemple de ce travail:

enter image description here

Voici un exemple de ce gauchissement l'image, parce que je touché près du bord:

enter image description here

+0

Pourriez-vous simplement vérifier si le contact se produit en dehors de l'image et l'ignorer si c'est le cas? – BallpointBen

+0

C'est une idée intelligente. J'y ai pensé, mais techniquement le toucher est à l'intérieur de l'image. Une partie du rectum tombe juste à l'extérieur et je voudrais toujours donner à l'utilisateur la possibilité de recadrer s'il touche près du bord. – user4812000

+0

Cela a du sens. Savez-vous pourquoi le rectangle jaune de la deuxième image contient des données d'image décalées? Vous pouvez voir que lui et l'image originale seraient alignés si vous avez déplacé le rectangle à gauche. – BallpointBen

Répondre

3

CGImageCreateWithImageInRect (screenshot.CGImage, crop) renvoie en effet une version recadrée. Voici le commentaire pertinent de la documentation:

Quartz effectue ces tâches pour créer le sous-image:

  • Permet de régler la zone spécifiée par le paramètre rect à bornes intégrales en appelant la fonction CGRectIntegral.

  • Intersecte le résultat avec un rectangle dont l'origine est (0,0) et dont la taille est égale à la taille de l'image spécifiée par le paramètre image.

  • Référence les pixels dans le rectangle résultant, en traitant le premier pixel dans le rectangle comme l'origine de la sous-image.

Une façon simple de résoudre ce problème est d'ajuster la position du UIImageView résultant donc il est correct pour sa taille. Voici le calcul pertinent:

let screenshotBounds = CGRectMake(0.0, 0.0, screenshot.size.width, screenshot.size.height) 
let cropIntegral = CGRectIntegral(crop) 
let cropIntersection = CGRectIntersection(cropIntegral, screenshotBounds) 
bgImage.center = CGPoint(CGRectGetMidX(cropIntersection), CGRectGetMidY(cropIntersection)) 

cropIntersection est le rectangle de délimitation de notre image extraite (après les deux premières étapes indiquées dans la documentation). Par conséquent, nous pouvons l'utiliser pour positionner l'imageView au même endroit dans l'image originale.

+0

fonctionne parfaitement! J'apprécie que vous intégriez également mes variables! – user4812000