[英]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.