Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios GPUImage裁剪到CGRect并旋转_Ios_Swift_Gpuimage - Fatal编程技术网

Ios GPUImage裁剪到CGRect并旋转

Ios GPUImage裁剪到CGRect并旋转,ios,swift,gpuimage,Ios,Swift,Gpuimage,给定一个CGRect,我想使用GPUImage来裁剪视频。例如,如果rect是(0,0,50,50),则视频将在(0,0)处剪切,每侧的长度为50 让我感到困惑的是,GPUImageCropFilter不采用矩形,而是采用值范围为0到1的标准化裁剪区域。我的直觉是: let assetSize = CGSizeApplyAffineTransform(videoTrack.naturalSize, videoTrack.preferredTransform) let cropRect = CGR

给定一个
CGRect
,我想使用GPUImage来裁剪视频。例如,如果rect是
(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()
        }

正如您所注意到的,GPUImageCropFilter在标准化坐标中采用矩形。这是正确的,只需将X分量(origin.X和size.width)除以图像的宽度,将Y分量除以高度,即可将以像素为单位的CGRect转换为标准化坐标

您不需要使用
forceProcessingAtSize()
,因为裁剪将自动输出适当裁剪大小的图像。电影编剧的大小应该与这个裁剪的大小相匹配,您应该从原始CGRect中了解到这一点

你引入的一个复杂因素是旋转。如果需要在裁剪之外应用旋转,则可能需要检查并确保不需要为裁剪区域交换X和Y。如果两者需要交换,则这一点在输出中应该很明显


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

正如您所注意的,GPUImageCropFilter在标准化坐标中采用矩形。这是正确的,只需将X分量(origin.X和size.width)除以图像的宽度,将Y分量除以高度,即可将以像素为单位的CGRect转换为标准化坐标

您不需要使用
forceProcessingAtSize()
,因为裁剪将自动输出适当裁剪大小的图像。电影编剧的大小应该与这个裁剪的大小相匹配,您应该从原始CGRect中了解到这一点

你引入的一个复杂因素是旋转。如果需要在裁剪之外应用旋转,则可能需要检查并确保不需要为裁剪区域交换X和Y。如果两者需要交换,则这一点在输出中应该很明显


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

是的,我认为您是对的,因为如果我应用
videoTrack.preferredTransform
到裁剪区域,然后进行裁剪和输出,输出的视频是旋转的,但按我所希望的方式进行裁剪。然后,如果我通过一个旋转过滤器运行它,旋转是有效的,但我会在视频的一侧看到黑色的条带,这些条带不存在,也不应该存在。我发布了我最终能够工作的代码。事实证明,我根本不需要使用旋转过滤器,我只是将电影编写器的变换设置为视频轨迹的变换。不过,有两件事你可能知道一些。当我导出一部电影并通过xcode打开我的文档文件夹时,会发生两件事:1)我剪切的所有电影的旁边都有一个黑条。2) 当我单击播放电影时,quicktime会转换文件,并且转换过程中会去掉边栏。知道这是怎么回事吗?是的,我想你是对的,因为如果我应用
videoTrack.preferredTransform
到我的裁剪区域,然后裁剪和输出,输出的视频会旋转,但裁剪的方式正是我想要的。然后,如果我通过一个旋转过滤器运行它,旋转是有效的,但我会在视频的一侧看到黑色的条带,这些条带不存在,也不应该存在。我发布了我最终能够工作的代码。事实证明,我根本不需要使用旋转过滤器,我只是将电影编写器的变换设置为视频轨迹的变换。不过,有两件事你可能知道一些。当我导出一部电影并通过xcode打开我的文档文件夹时,会发生两件事:1)我剪切的所有电影的旁边都有一个黑条。2) 当我单击播放电影时,quicktime会转换文件,并且转换过程中会去掉边栏。知道那是怎么回事吗?