裁剪区域与iOS中的选定区域不同?

时间:2015-04-04 19:03:16

标签: ios xcode video cgrect avasset

这是github https://github.com/spennyf/cropVid/tree/master上的链接来尝试一下你的自我,看看我在说什么,需要1分钟来测试。谢谢!

我正在拍摄一个带有正方形的视频,以显示vid的哪一部分将被裁剪。像这样:

enter image description here

现在我正在做一张纸,正方形有4条线,顶部和底部有半条线差异。然后我使用我将发布的代码裁剪视频,但是当我显示视频时,我看到了这个(忽略背景和绿色圆圈):

enter image description here

正如你所看到的那样,有超过四行,所以我将它设置为裁剪某个部分,但是当我使用相机中显示的相同矩形时,它会添加更多,并且是相同的矩形。曾经作物?

所以我的问题是为什么裁剪的尺寸不一样?

以下是裁剪和显示方式:

//this is the square on the camera
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-80)];
    UIImageView *image = [[UIImageView alloc] init];
    image.layer.borderColor=[[UIColor whiteColor] CGColor];
image.frame = CGRectMake(self.view.frame.size.width/2 - 58 , 100 , 116, 116);
    CALayer *imageLayer = image.layer;
    [imageLayer setBorderWidth:1];
[view addSubview:image];
    [picker setCameraOverlayView:view];

//this is crop rect
CGRect rect = CGRectMake(self.view.frame.size.width/2 - 58, 100, 116, 116);
[self applyCropToVideoWithAsset:assest AtRect:rect OnTimeRange:CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(assest.duration.value, 1))
                    ExportToUrl:exportUrl ExistingExportSession:exporter WithCompletion:^(BOOL success, NSError *error, NSURL *videoUrl) {
//here is player
AVPlayer *player = [AVPlayer playerWithURL:videoUrl];

                            AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:player];
layer.frame = CGRectMake(self.view.frame.size.width/2 - 58, 100, 116, 116);
}];

以下是执行裁剪的代码:

- (UIImageOrientation)getVideoOrientationFromAsset:(AVAsset *)asset
{
    AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGSize size = [videoTrack naturalSize];
CGAffineTransform txf = [videoTrack preferredTransform];

if (size.width == txf.tx && size.height == txf.ty)
    return UIImageOrientationLeft; //return UIInterfaceOrientationLandscapeLeft;
else if (txf.tx == 0 && txf.ty == 0)
    return UIImageOrientationRight; //return UIInterfaceOrientationLandscapeRight;
else if (txf.tx == 0 && txf.ty == size.width)
    return UIImageOrientationDown; //return UIInterfaceOrientationPortraitUpsideDown;
else
    return UIImageOrientationUp;  //return UIInterfaceOrientationPortrait;
}

以下是裁剪代码的其余部分:

- (AVAssetExportSession*)applyCropToVideoWithAsset:(AVAsset*)asset AtRect:(CGRect)cropRect OnTimeRange:(CMTimeRange)cropTimeRange ExportToUrl:(NSURL*)outputUrl ExistingExportSession:(AVAssetExportSession*)exporter WithCompletion:(void(^)(BOOL success, NSError* error, NSURL* videoUrl))completion
{

//    NSLog(@"CALLED");
//create an avassetrack with our asset
AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

//create a video composition and preset some settings
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.frameDuration = CMTimeMake(1, 30);

CGFloat cropOffX = cropRect.origin.x;
CGFloat cropOffY = cropRect.origin.y;
CGFloat cropWidth = cropRect.size.width;
CGFloat cropHeight = cropRect.size.height;
//    NSLog(@"width: %f - height: %f - x: %f - y: %f", cropWidth, cropHeight, cropOffX, cropOffY);

videoComposition.renderSize = CGSizeMake(cropWidth, cropHeight);

//create a video instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = cropTimeRange;

AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];

UIImageOrientation videoOrientation = [self getVideoOrientationFromAsset:asset];

CGAffineTransform t1 = CGAffineTransformIdentity;
CGAffineTransform t2 = CGAffineTransformIdentity;

switch (videoOrientation) {
    case UIImageOrientationUp:
        t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.height - cropOffX, 0 - cropOffY );
        t2 = CGAffineTransformRotate(t1, M_PI_2 );
        break;
    case UIImageOrientationDown:
        t1 = CGAffineTransformMakeTranslation(0 - cropOffX, clipVideoTrack.naturalSize.width - cropOffY ); // not fixed width is the real height in upside down
        t2 = CGAffineTransformRotate(t1, - M_PI_2 );
        break;
    case UIImageOrientationRight:
        t1 = CGAffineTransformMakeTranslation(0 - cropOffX, 0 - cropOffY );
        t2 = CGAffineTransformRotate(t1, 0 );
        break;
    case UIImageOrientationLeft:
        t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.width - cropOffX, clipVideoTrack.naturalSize.height - cropOffY );
        t2 = CGAffineTransformRotate(t1, M_PI  );
        break;
    default:
        NSLog(@"no supported orientation has been found in this video");
        break;
}

CGAffineTransform finalTransform = t2;
[transformer setTransform:finalTransform atTime:kCMTimeZero];

//add the transformer layer instructions, then add to video composition
instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];

//Remove any prevouis videos at that path
[[NSFileManager defaultManager]  removeItemAtURL:outputUrl error:nil];

if (!exporter){
    exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ;
}
// assign all instruction for the video processing (in this case the transformation for cropping the video
exporter.videoComposition = videoComposition;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
if (outputUrl){
    exporter.outputURL = outputUrl;
    [exporter exportAsynchronouslyWithCompletionHandler:^{
        switch ([exporter status]) {
            case AVAssetExportSessionStatusFailed:
                NSLog(@"crop Export failed: %@", [[exporter error] localizedDescription]);
                if (completion){
                    dispatch_async(dispatch_get_main_queue(), ^{
                        completion(NO,[exporter error],nil);
                    });
                    return;
                }
                break;
            case AVAssetExportSessionStatusCancelled:
                NSLog(@"crop Export canceled");
                if (completion){
                    dispatch_async(dispatch_get_main_queue(), ^{
                        completion(NO,nil,nil);
                    });
                    return;
                }
                break;
            default:
                break;
        }
        if (completion){
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(YES,nil,outputUrl);
            });
        }

    }];
}

return exporter;
}

所以我的问题是为什么视频区域与裁剪/相机区域不一样,当我使用完全相同的坐标和大小的方块时?

1 个答案:

答案 0 :(得分:-1)

也许Check This Previous Question

看起来它可能与您遇到的情况类似。该问题的用户建议采用这种方式裁剪:

CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

我希望这有助于或至少为您提供正确方向的开端。