如何在图像上应用Perspective 3d Transform并将该图像保存在文档目录中

时间:2017-01-05 11:39:23

标签: ios objective-c uiimageview transform layer

我正在通过以下代码在图像层上应用3D变换。

UIImageView *view = (UIImageView *)[recognizer view];
CGPoint translation = [recognizer translationInView:self.view];
CGPoint newCenter = view.center;
newCenter.x += translation.x;
newCenter.y += translation.y;
view.center = newCenter;
[recognizer setTranslation:CGPointZero inView:self.view];

以下是将点转换为变换。

UIView+Quadrilateral

[self.view transformToFitQuadTopLeft:self.topLeftControl.center
                                       topRight:self.topRightControl.center
                                     bottomLeft:self.bottomLeftControl.center
                                    bottomRight:self.bottomRightControl.center];

为了将变换图像保存到UIImage,我使用renderInContext使用了以下代码。

UIGraphicsBeginImageContext(view.frame.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

和第二次使用drawViewHierarchyInRect

UIGraphicsBeginImageContextWithOptions(self.toothImageView_1.bounds.size, NO, 0);
BOOL ok = [self.toothImageView_1 drawViewHierarchyInRect:self.toothImageView_1.bounds afterScreenUpdates:YES];

UIImage *img = nil;

if( ok )
{
    image = UIGraphicsGetImageFromCurrentImageContext();
}

self.imageView.image = image;
UIGraphicsEndImageContext();

我正在获得原始框架方形图像而不是变换图像。我实际上需要将一个3d变换图像保存在文档目录中。

提前致谢。任何建议和答案都是最受欢迎的。

1 个答案:

答案 0 :(得分:2)

您可以通过Apple

提供的CoreImage Framework来完成
- (UIImage *)imageByTransformingImage:(UIImage *)image {

    if (image == nil) {
        return nil; //image not found
    }
    CIImage *coreImage = [CIImage imageWithData:UIImagePNGRepresentation(image)];

    if (!coreImage) {
        return nil; // image is not converted in core image
    }

    //assuming that topLeft, topRight, bottomRight and bottomLeft stored in transformationDict
    NSDictionary *dict = [self.transformationDict valueForKey:@"Corners"];

    CGPoint topLeftPoint = CGPointFromString([dict valueForKey:kTopLeft]);
    CGPoint topRightPoint = CGPointFromString([dict valueForKey:kTopRight]);
    CGPoint bottomRightPoint = CGPointFromString([dict valueForKey:kBottomRight]);
    CGPoint bottomLeftPoint = CGPointFromString([dict valueForKey:kBottomLeft]);

    CIFilter *perspectiveTransformation = [CIFilter filterWithName:@"CIPerspectiveTransform"];
    [perspectiveTransformation setValue:[CIVector vectorWithCGPoint:topLeftPoint] forKey:@"inputTopLeft"];
    [perspectiveTransformation setValue:[CIVector vectorWithCGPoint:topRightPoint] forKey:@"inputTopRight"];
    [perspectiveTransformation setValue:[CIVector vectorWithCGPoint:bottomRightPoint] forKey:@"inputBottomRight"];
    [perspectiveTransformation setValue:[CIVector vectorWithCGPoint:bottomLeftPoint] forKey:@"inputBottomLeft"];
    [perspectiveTransformation setValue:coreImage forKey:kCIInputImageKey];

    CIImage *resultImage = [perspectiveTransformation outputImage];
    CIContext *ciContext = [CIContext contextWithOptions:nil];
    CGImageRef cgImageRef = [ciContext createCGImage:resultImage fromRect:[resultImage extent]];
    UIImage *transformedImage = [UIImage imageWithCGImage:cgImageRef];

    return transformedImage;
    //transformed image will be flipped image you need to flip context to get correct UIImage
}

Swift版本

func imageByTransformingImage(image: UIImage?) -> UIImage? {

    guard image != nil else {
        return nil;
    }

    if let coreImage = CIImage(data: UIImagePNGRepresentation(image!)!) {

        //assuming that topLeft, topRight, bottomRight and bottomLeft stored in transformationDict
        let dict = self.transformationDict.valueForKey("Corners");

        let dict = [String : Any]();
        let topLeftPoint = CGPointFromString(dict["TopLeftCorner"] as! String);
        let topRightPoint = CGPointFromString(dict["TopRightCorner"] as! String);
        let bottomRightPoint = CGPointFromString(dict["BottomRightCorner"] as! String);
        let bottomLeftPoint = CGPointFromString(dict["BottomLeftCorner"] as! String);

        if let perspectiveTransformation = CIFilter(name: "CIPerspectiveTransform") {
            perspectiveTransformation.setValue(CIVector(CGPoint: topLeftPoint), forKey: "inputTopLeft");
            perspectiveTransformation.setValue(CIVector(CGPoint:topRightPoint), forKey: "inputTopRight");
            perspectiveTransformation.setValue(CIVector(CGPoint:bottomRightPoint), forKey: "inputBottomRight");
            perspectiveTransformation.setValue(CIVector(CGPoint:bottomLeftPoint), forKey: "inputBottomLeft");
            perspectiveTransformation.setValue(coreImage, forKey:kCIInputImageKey);

            if let resultImage = perspectiveTransformation.outputImage {
                let ciContext = CIContext()
                let cgImageRef = ciContext.createCGImage(resultImage, fromRect: resultImage.extent) as CGImageRef

                return UIImage(CGImage: cgImageRef);

                //transformed image will be flipped image you need to flip context to get correct UIImage
            }

        }

    }
    return nil;
}