2017-05-10 90 views
5

Kod zostanie dodany do Github, aby umożliwić zrozumienie prawdziwego problemu.Jak scalić dwie jednostki UII z zachowaniem proporcji i rozmiaru?


To hierarchia:

-- ViewController.View P [width: 375, height: 667] 
---- UIImageView A  [width: 375, height: 667] Name: imgBackground 
         [A is holding an image of size(1287,1662)] 
---- UIImageView B  [width: 100, height: 100] Name: imgForeground 
         [B is holding an image of size(2400,982)] 

Próbuję połączyć A z B, ale wynik jest rozciągnięta.

Jest to kod seryjnej:

func mixImagesWith(frontImage:UIImage?, backgroundImage: UIImage?, atPoint point:CGPoint, ofSize signatureSize:CGSize) -> UIImage { 
    let size = self.imgBackground.frame.size 
    UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) 
    backgroundImage?.draw(in: CGRect.init(x: 0, y: 0, width: size.width, height: size.height)) 
    frontImage?.draw(in: CGRect.init(x: point.x, y: point.y, width: signatureSize.width, height: signatureSize.height)) 
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 
    return newImage 
} 

Uwaga:

Oto zrzut ekranu, aby zrozumieć problem:

enter image description here

Co należy zrobić, aby uzyskać prawidłowe wyjście z funkcji korespondencji seryjnej?

Odpowiedz

2

Masz dwa błędy w kodzie:

  1. Należy również obliczyć aspekt dla dokumentu obrazu do dopasuj go do UIImageView. W mergeImages() wymienić:

    img.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) 
    

    z:

    img.draw(in: getAspectFitFrame(sizeImgView: size, sizeImage: img.size)) 
    
  2. Przy obliczaniu proporcji centrum, które obrazu poziomo/pionowo, gdy jego szerokość/wysokość mniej niż UIImageView szerokości/wysokości. Ale zamiast porównując newWidth i newHeight należy porównać czynniki:

    if hfactor > vfactor { 
        y = (sizeImgView.height - newHeight)/2 
    } else { 
        x = (sizeImgView.width - newWidth)/2 
    } 
    
+0

Cześć Michał, dzięki za odpowiedź. Jest jeden mały problem z tym. Ponieważ dwa obrazy mają różną wielkość. Po scaleniu zauważalna jest różna zmiana pochodzenia dla 'UIImage B'. Co należy zrobić, aby uzyskać dokładne pochodzenie w odniesieniu do oryginalnego rozmiaru obrazu (np. "UIImage A")? – Hemang

+0

@Hemang Testowałem na różnych emulatorach i nie widzę żadnej zmiany pochodzenia po scaleniu przy użyciu dostarczonego kodu źródłowego. Czy mógłbyś zadać osobne pytanie? – mixel

+0

Dzięki, Michael, oto nowe [pytanie] (http://stackoverflow.com/questions/44095532/how-to-merge-two-uiimages-whi--keeping-their-position-size-and-aspect-ratios) . – Hemang

2

Spróbuj miech kod działa dla mnie, mam nadzieję, że pracuje dla Ciebie,

func addWaterMarkToImage(img:UIImage, sizeWaterMark:CGRect, waterMarkImage:UIImage, completion : ((UIImage)->())?){ 
    handler = completion 
    let img2:UIImage = waterMarkImage 
    let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height) 
    UIGraphicsBeginImageContext(img.size) 
    img.draw(in: rect) 
    let frameAspect:CGRect = getAspectFitFrame(sizeImgView: sizeWaterMark.size, sizeImage: waterMarkImage.size) 
    let frameOrig:CGRect = CGRect(x: sizeWaterMark.origin.x+frameAspect.origin.x, y: sizeWaterMark.origin.y+frameAspect.origin.y, width: frameAspect.size.width, height: frameAspect.size.height) 
    img2.draw(in: frameOrig, blendMode: .normal, alpha: 1) 

    let result = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    if handler != nil { 
     handler!(result!) 
    } 
} 
//MARK - Get Aspect Fit frame of UIImage 
func getAspectFitFrame(sizeImgView:CGSize, sizeImage:CGSize) -> CGRect{ 

    let imageSize:CGSize = sizeImage 
    let viewSize:CGSize = sizeImgView 

    let hfactor : CGFloat = imageSize.width/viewSize.width 
    let vfactor : CGFloat = imageSize.height/viewSize.height 

    let factor : CGFloat = max(hfactor, vfactor) 

    // Divide the size by the greater of the vertical or horizontal shrinkage factor 
    let newWidth : CGFloat = imageSize.width/factor 
    let newHeight : CGFloat = imageSize.height/factor 

    var x:CGFloat = 0.0 
    var y:CGFloat = 0.0 
    if newWidth > newHeight{ 
     y = (sizeImgView.height - newHeight)/2 
    } 
    if newHeight > newWidth{ 
     x = (sizeImgView.width - newWidth)/2 
    } 
    let newRect:CGRect = CGRect(x: x, y: y, width: newWidth, height: newHeight) 

    return newRect 

}