2017-05-10 19 views
5

Mã được thêm vào Github để cho bạn hiểu vấn đề thực sự.Làm cách nào để hợp nhất hai UIImages trong khi vẫn giữ tỷ lệ cỡ ảnh?


Đây là hệ thống phân cấp:

-- 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)] 

Tôi cố gắng để kết hợp A với B nhưng kết quả được kéo dài.

Đây là mã hợp nhất:

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 
} 

Lưu ý:

  • .contentMode = .scaleAspectFit
  • công trình Mã nhưng kết quả được kéo dài.
  • Xem dòng này bằng mã, let size = self.imgBackground.frame.size - Tôi cần thay đổi điều này để khắc phục sự cố. Find the origin of subview with respect to UIImage size

Dưới đây là ảnh chụp màn hình để hiểu được vấn đề:

enter image description here

Tôi nên làm gì để có được kết quả đúng chức năng merge?

Trả lời

2

Bạn có hai lỗi trong mã của bạn:

  1. Bạn cũng nên tính toán khía cạnh cho hình ảnh tài liệu để phù hợp với nó vào UIImageView. Trong mergeImages() thay thế:

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

    với:

    img.draw(in: getAspectFitFrame(sizeImgView: size, sizeImage: img.size)) 
    
  2. Khi tính toán khía cạnh bạn hình ảnh trung tâm theo chiều ngang/chiều dọc nếu chiều rộng của nó/chiều cao ít hơn UIImageView chiều rộng/chiều cao. Nhưng thay vì so sánh newWidthnewHeight bạn nên so sánh các yếu tố:

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

Hi Michael, cảm ơn vì câu trả lời của bạn. Có một vấn đề nhỏ với điều này. Vì hai hình ảnh có kích thước khác nhau. Sau khi hợp nhất, có sự khác biệt đáng chú ý về các thay đổi xuất xứ đối với 'UIImage B'. Tôi nên làm gì để có được nguồn gốc chính xác đối với kích thước hình ảnh ban đầu (tức là 'UIImage A')? – Hemang

+0

@Hemang Tôi đã thử nghiệm trên các trình giả lập khác nhau và tôi không thấy bất kỳ thay đổi xuất xứ nào sau khi hợp nhất bằng cách sử dụng mã nguồn bạn đã cung cấp. Bạn có thể đặt câu hỏi riêng? – mixel

+0

Cảm ơn, Michael, đây là [câu hỏi mới] (http://stackoverflow.com/questions/44095532/how-to-merge-two-uiimages-while-keeping-their-position-size-and-aspect-ratios) . – Hemang

2

thử đoạn code dưới đây nó làm việc cho tôi, hy vọng nó làm việc cho bạn quá,

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 

} 
Các vấn đề liên quan