簡體   English   中英

GPUImage裁剪以CGRect並旋轉

[英]GPUImage crop to CGRect and rotate

給定一個CGRect ,我想使用GPUImage裁剪視頻。 例如,如果rect為(0, 0, 50, 50) 0,0,50,50 (0, 0, 50, 50) ,則視頻將在(0,0)處裁剪,每邊的長度為50。

讓我感到GPUImageCropFilter是, 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。 如果需要交換兩者,這在輸出中應該很明顯。

前一陣子同時應用旋轉有一些錯誤,我不記得是否修復了所有這些錯誤。 如果沒有,您可以在裁剪之前或之后插入一個虛擬濾鏡(伽瑪或亮度設置為默認值),然后在該階段應用旋轉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM