Preface:

This paper undertakes:

Another realization of photo selection area function: add action effect

And two others

Next, the selection of locale – dependent processing

Rotate, select the region, and make a perspective correction filter for the selected region

And to simplify things,

The project is set to iPhone portrait only

It runs on the iPad

This is a picture taken after a left-handed rotation

The problem

Using the filter (perspective correction) is simple, the rotated image is likely to be different from the image before the rotation, which affects the effect of the filter

scenario

IPad, landscape up by default, portrait iPhone app,

Set the camera to

connection? .videoOrientation = AVCaptureVideoOrientation.portrait session.sessionPreset = .hd1280x720Copy the code

Taken photos, orientation to pic.imageOrientation =. Right

The size is

-width: 720.0 - height: 1280.0Copy the code
And just to simplify things

Select crop View frame = Image View frame

The coordinates of the four corners above crop view, based on the bounds of crop view,

That is, the coordinates of the four corners above crop view, based on CGRect(cgPoint.zero, frame. Size of image view).

Yes, the rotated image orientation is always upward

You get the picture facing, to the right. The filters use normal development coordinates and the results are confusing.

implementation

Simple filter code

// The first argument, picture view bounds, uses size

// The second argument, the image to be processed

// The third parameter, four coordinates

static public func cropImage(in rect: CGRect,with img: UIImage, quad corners: [CGPoint]) throws -> UIImage {let imgSize = img.size // Find the bounds of the picture view, Image aspect ratio frame let f = AVMakeRect(aspectRatio: imgSize, insideRect: Let quad = height. map {(pt) -> CGPoint in return pt.inner(img: imgSize, relative:) f.size) } let ciImage = CIImage(image: img) // print("rect: ", rect, "corners: ",corners) let perspectiveCorrection = CIFilter(name: "Perspectivecorrection ") // Let orderedQuad = try orderPointsInQuadrangle(quad: Let context = CIContext(options: nil) // print(" Ordered Quad: ", orderedQuad, "imgSize: ", imgSize) guard let transform = perspectiveCorrection else { throw SECropError.unknown } transform.setValue(CIVector(cgPoint: orderedQuad[0].cartesian(for: imgSize)), forKey: "inputTopLeft") transform.setValue(CIVector(cgPoint: orderedQuad[1].cartesian(for: imgSize)), forKey: "inputTopRight") transform.setValue(CIVector(cgPoint: orderedQuad[2].cartesian(for: imgSize)), forKey: "inputBottomRight") transform.setValue(CIVector(cgPoint: orderedQuad[3].cartesian(for: imgSize)), forKey: "inputBottomLeft") transform.setValue(ciImage, forKey: kCIInputImageKey) guard let perspectiveCorrectedImg = transform.outputImage, let cgImage = context.createCGImage(perspectiveCorrectedImg, from: perspectiveCorrectedImg.extent) else { throw SECropError.unknown } return UIImage(cgImage: cgImage, scale: img.scale, orientation: img.imageOrientation) }Copy the code

Error with filter:

In addition to the orientation problem,

  • And the coordinates are out of order, must be left -> right -> right -> left – down

  • Coordinate enlargement error, too large, out of area of image

After taking photos, image processing

func picTaken(img imgData: Data){ if let pic = UIImage(data: ImgData){if pic.imageOrientation ==. Right {// the iPad, after the orientation, takedImage = pic.up.image(Rotated: 1) } else{ takedImage = pic } } picCommon() }Copy the code

Change towards



extension UIImage{

    var up: UIImage{
        image(orientation: .up)
    }

    func image(orientation orient: UIImage.Orientation) -> UIImage{
        if let cg = cgImage{
            return UIImage(cgImage: cg, scale: scale, orientation: orient)
        }
        else{
            return self
        }
    }
    

}

Copy the code

The rotation code, which is pretty simple,

I didn’t do fix orientation,

See Github Repo for details

Image preprocessing before filtering

let idx = Int(angleX) guard let corners = cropView.cornerLocations, let img = takedImage? .image(rotated: Idx) else {return} ImageView rotate tranform var b = takediMageView. bounds if idx % 2! Var b = takediMageView. bounds if idx % 2! = 0{ let s = b.size.flip b.size = s } let croppedImage = try SEQuadrangleHelper.cropImage(in: b, with: img, quad: corners)Copy the code

After the filter, change the image orientation

Var final = croppedImage // if idx is negative, idx % 4 is negative Let k = (idx % 4 + 4) % 4 switch k {case 1: // Set github repo final = croppedimage.left case 2: // set github repo final = croppedimage.left case 2: final = croppedImage.down case 3: final = croppedImage.right default: () } takedImageView.image = finalCopy the code

In addition, click the rotate button

@objc func rotateBtnClickX(){angleX -= 1; // Take dimageView. transform = CGAffineTransform(rotationAngle: Imgsingleangle. time * angleX) let idx = Int(angleX) // Frame var inS = areaInner if idx % 2! Frame = inS cropView.refresh(frame: inS)} {// Frame is horizontal, there is a different frame inS = areaInnerRotateLeft} takediMageView.frame = inS cropView.refresh(frame: inS)}Copy the code

github repo