GPUImage裁剪为CGRect并旋转

时间:2016-05-05 02:17:00

标签: ios swift gpuimage

鉴于CGRect,我想使用GPUImage裁剪视频。例如,如果矩形为(0, 0, 50, 50),则视频将在(0,0)处裁剪,每边长度为50。

投掷我的是GPUImageCropFilter没有取矩形,而是规范化的裁剪区域,其值介于0到1之间。我的直觉是:

let assetSize = CGSizeApplyAffineTransform(videoTrack.naturalSize, videoTrack.preferredTransform)
let cropRect = CGRect(x: frame.minX/assetSize.width,
                y: frame.minY/assetSize.height,
                width: frame.width/assetSize.width,
                height: frame.height/assetSize.height)

根据传入资产的大小计算裁剪区域。然后:

// Filter
let cropFilter = GPUImageCropFilter(cropRegion: cropRect)
let url = NSURL(fileURLWithPath: "\(NSTemporaryDirectory())\(String.random()).mp4")
let movieWriter = GPUImageMovieWriter(movieURL: url, size: assetSize)
movieWriter.encodingLiveVideo = false
movieWriter.shouldPassthroughAudio = false

// add targets
movieFile.addTarget(cropFilter)
cropFilter.addTarget(movieWriter)

cropFilter.forceProcessingAtSize(frame.size)
cropFilter.setInputRotation(kGPUImageRotateRight, atIndex: 0)

电影作家的大小应该是多少?难道不是我要剪裁的框架尺寸吗?我应该使用forceProcessingAtSize我的裁剪框尺寸值吗?

完整的代码示例会很棒;我已经尝试了几个小时,而且我似乎无法获得我想要的视频部分。

最终:

if let videoTrack = self.asset.tracks.first {
            let movieFile = GPUImageMovie(asset: self.asset)
            let transformedRegion = CGRectApplyAffineTransform(region, videoTrack.preferredTransform)

            // Filters
            let cropFilter = GPUImageCropFilter(cropRegion: transformedRegion)

            let url = NSURL(fileURLWithPath: "\(NSTemporaryDirectory())\(String.random()).mp4")
            let renderSize = CGSizeApplyAffineTransform(videoTrack.naturalSize, CGAffineTransformMakeScale(transformedRegion.width, transformedRegion.height))

            let movieWriter = GPUImageMovieWriter(movieURL: url, size: renderSize)
            movieWriter.transform = videoTrack.preferredTransform

            movieWriter.encodingLiveVideo = false
            movieWriter.shouldPassthroughAudio = false

            // add targets
            // http://stackoverflow.com/questions/37041231/gpuimage-crop-to-cgrect-and-rotate
            movieFile.addTarget(cropFilter)
            cropFilter.addTarget(movieWriter)

            movieWriter.completionBlock = {
                observer.sendNext(url)
                observer.sendCompleted()
            }

            movieWriter.failureBlock = { _ in
                observer.sendFailed(.VideoCropFailed)
            }

            disposable.addDisposable {
                cropFilter.removeTarget(movieWriter)
                movieWriter.finishRecording()
            }

            movieWriter.startRecording()
            movieFile.startProcessing()
        }

1 个答案:

答案 0 :(得分:3)

正如您所注意到的,GPUImageCropFilter在标准化坐标中接受一个矩形。您正好在正确的轨道上,因为您只需将CGRect(以像素为单位)转换为标准化坐标,方法是将X分量(origin.x和size.width)除以图像的宽度和Y分量。高度。

您不需要使用forceProcessingAtSize(),因为裁剪会自动输出适当裁剪尺寸的图像。电影作家的大小应该与这个裁剪的大小相匹配,你应该从原来的CGRect中知道。

您介绍的一个复杂因素是旋转。如果除了作物之外还需要应用旋转,您可能需要检查并确保不需要将X和Y替换为裁剪区域。如果两者需要交换,这在输出中应该是显而易见的。

有一些错误与前一段时间的作物同时应用旋转,我不记得我是否修复了所有这些。如果我没有,您可以在裁剪之前或之后插入虚拟滤镜(伽马或亮度设置为默认值)并在该阶段应用旋转。