ios - GPUImage 裁剪为 CGRect 并旋转

标签 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)

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

// 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()
        }

最佳答案

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

您不需要使用 forceProcessingAtSize(),因为裁剪会自动输出适当裁剪尺寸的图像。电影作者的尺寸应与裁剪后的尺寸相匹配,您应该从原始 CGRect 中知道这一点。

您介绍的一个并发症是旋转。如果除了裁剪之外还需要应用旋转,您可能需要检查并确保不需要为裁剪区域交换 X 和 Y。如果需要交换两者,这在输出中应该很明显。

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

关于ios - GPUImage 裁剪为 CGRect 并旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37041231/

相关文章:

ios - 与 calabash ios 中的系统级警报对话框交互

ios - 在什么情况下 CLAuthorizationStatus "restricted"?

ios - 单元格中带有 UIWebView 的 UITableView 性能不佳

快速字典 : map within a map

用于 OCR 的 iOS UIImage 二值化 - 处理具有不同亮度的图像

ios - GPUImage - 将 GPUImageTransformFilter 匹配到正确的混合大小

ios - 如何在 iOS 的 URLByAppendingPathComponent 中添加自定义路径

ios - 类型 'String' 不符合协议(protocol) 'NilLiteralConvertiblle'

c++ - 如何从 Swift 中的 C++ 矩阵中检索值?

ios - 如何使用 Swift 语法在 GPUImage2 中将两个图像混合在一起