2017-05-05 4 views
1

사진을 찍은 후 녹색 뷰 파인더에있는 것을 캡처하려고합니다.스위프트의 AVCaptureVideoPreviewLayer에서 뷰 파인더 경계와 일치하는 AVFoundation에서 스틸 이미지 캡처

참조하십시오 이미지 :

image 1/3

image 2/3

image 3/3

이되는 코드가 현재 무엇을하고 있는지 :

사진을 촬영하기 전에 :

당신이 볼 수 있듯이 enter image description here

는 이미지가 확장 할 필요가있다 :

image 4/4

사진을 촬영 한 후 (이미지 결과의 규모가 녹색 뷰 파인더에 일치하지 않는, 정확하지 않습니다) 원래 녹색 뷰 파인더에 포함 된 내용에 맞 춥니 다. 올바른 배율을 계산할 때도 (iPhone 6의 경우 캡쳐 된 이미지의 크기에 1.334를 곱하면 작동하지 않습니다.)

아이디어가 있습니까? 이 문제를 해결하기 위해

답변

1

단계 :

첫째, 전체 크기의 이미지를 얻을 : 나는 또한 "correctlyOriented"라는있는 UIImage 클래스의 확장을 사용했다.

let correctImage = UIImage(data: imageData!)!.correctlyOriented() 

이 모든 작업은 iPhone 이미지의 회전을 방지하므로, 세로 이미지 (iPhone 하단의 홈 버튼으로 찍음)가 원하는 방향으로 표시됩니다. 즉, 확장은 아래와 같다 :

extension UIImage { 

func correctlyOriented() -> UIImage { 

if imageOrientation == .up { 
    return self 
} 

// We need to calculate the proper transformation to make the image upright. 
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 
var transform = CGAffineTransform.identity 

switch imageOrientation { 
case .down, .downMirrored: 
    transform = transform.translatedBy(x: size.width, y: size.height) 
    transform = transform.rotated(by: CGFloat.pi) 
case .left, .leftMirrored: 
    transform = transform.translatedBy(x: size.width, y: 0) 
    transform = transform.rotated(by: CGFloat.pi * 0.5) 
case .right, .rightMirrored: 
    transform = transform.translatedBy(x: 0, y: size.height) 
    transform = transform.rotated(by: -CGFloat.pi * 0.5) 
default: 
    break 
} 

switch imageOrientation { 
case .upMirrored, .downMirrored: 
    transform = transform.translatedBy(x: size.width, y: 0) 
    transform = transform.scaledBy(x: -1, y: 1) 
case .leftMirrored, .rightMirrored: 
    transform = transform.translatedBy(x: size.height, y: 0) 
    transform = transform.scaledBy(x: -1, y: 1) 
default: 
    break 
} 

// Now we draw the underlying CGImage into a new context, applying the transform 
// calculated above. 
guard 
    let cgImage = cgImage, 
    let colorSpace = cgImage.colorSpace, 
    let context = CGContext(data: nil, 
          width: Int(size.width), 
          height: Int(size.height), 
          bitsPerComponent: cgImage.bitsPerComponent, 
          bytesPerRow: 0, 
          space: colorSpace, 
          bitmapInfo: cgImage.bitmapInfo.rawValue) else { 
           return self 
} 

context.concatenate(transform) 

switch imageOrientation { 
case .left, .leftMirrored, .right, .rightMirrored: 
    context.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width)) 
default: 
    context.draw(cgImage, in: CGRect(origin: .zero, size: size)) 
} 

// And now we just create a new UIImage from the drawing context 
guard let rotatedCGImage = context.makeImage() else { 
    return self 
} 

return UIImage(cgImage: rotatedCGImage) 
} 

다음에, 높이 비율을 계산한다

let heightFactor = self.view.frame.height/correctImage.size.height 

높이 팩터에 기초하여 새로운 CGSize를 만들고 크기 조정 화상 함수 사용 (화상 크기를 조정 미도) iPhone 화면 9 종횡비 16 : VS 아이폰 카메라 : 3 화면비 지금

let newSize = CGSize(width: correctImage.size.width * heightFactor, height: correctImage.size.height * heightFactor) 

let correctResizedImage = self.imageWithImage(image: correctImage, scaledToSize: newSize) 

우리 인해 4 우리 기기와 동일한 높이이지만, 넓은 화상을 . 따라서, 장치 화면과 같은 크기로 이미지를 자르 :

let screenCrop: CGRect = CGRect(x: (newSize.width - self.view.bounds.width) * 0.5, 
               y: 0, 
               width: self.view.bounds.width, 
               height: self.view.bounds.height) 


var correctScreenCroppedImage = self.crop(image: correctResizedImage, to: screenCrop) 

마지막으로, 우리는 녹색 "뷰 파인더"에 의해 생성 된 "작물"를 복제 할 필요가있다. @damirstuhec

이 답변
let correctCrop: CGRect = CGRect(x: 0, 
              y: (correctScreenCroppedImage!.size.height * 0.5) - (correctScreenCroppedImage!.size.width * 0.5), 
              width: correctScreenCroppedImage!.size.width, 
              height: correctScreenCroppedImage!.size.width) 

var correctCroppedImage = self.crop(image: correctScreenCroppedImage!, to: correctCrop) 

신용 간다 : 그래서, 우리는 최종 이미지 일치를 만들기 위해 다른 작물을 수행

관련 문제