AVAssetTrack 的preferredTransform 有时候好像不对。这怎么能解决?
AVAssetTrack's preferredTransform sometimes seems to be wrong. How can this be fixed?
我正在使用 AVAssetExportSession
在 iOS 应用中导出视频。为了以正确的方向呈现视频,我使用了 AVAssetTrack
的 preferredTransform
。对于某些源视频,这个 属性 似乎有一个错误的值,并且视频在结果中出现偏移或全黑。我该如何解决这个问题?
preferredTransform
是 CGAffineTransform
。属性 a
、b
、c
、d
是反射矩阵和旋转矩阵的串联,属性 tx
和 ty
描述了平移.在我观察到 preferredTransform
不正确的所有情况下,reflection/rotation 部分似乎是正确的,只有翻译部分包含错误的值。一个可靠的修复似乎是检查 a
、b
、c
、d
(总共八个案例,每个对应 UIImageOrientation
中的一个案例)和相应地更新 tx
和 ty
:
extension AVAssetTrack {
var fixedPreferredTransform: CGAffineTransform {
var t = preferredTransform
switch(t.a, t.b, t.c, t.d) {
case (1, 0, 0, 1):
t.tx = 0
t.ty = 0
case (1, 0, 0, -1):
t.tx = 0
t.ty = naturalSize.height
case (-1, 0, 0, 1):
t.tx = naturalSize.width
t.ty = 0
case (-1, 0, 0, -1):
t.tx = naturalSize.width
t.ty = naturalSize.height
case (0, -1, 1, 0):
t.tx = 0
t.ty = naturalSize.width
case (0, 1, -1, 0):
t.tx = naturalSize.height
t.ty = 0
case (0, 1, 1, 0):
t.tx = 0
t.ty = 0
case (0, -1, -1, 0):
t.tx = naturalSize.height
t.ty = naturalSize.width
default:
break
}
return t
}
}
我认为我最终做了一些更稳健的事情,我根据最终的结果取消了转换:
auto naturalFrame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
auto preferredFrame = CGRectApplyAffineTransform(naturalFrame, preferredTransform);
preferredTransform.tx -= preferredFrame.origin.x;
preferredTransform.ty -= preferredFrame.origin.y;
请注意,您不能只对 (0, 0)
应用变换,因为 CGRect.origin
会考虑翻转等因素。
我正在使用 AVAssetExportSession
在 iOS 应用中导出视频。为了以正确的方向呈现视频,我使用了 AVAssetTrack
的 preferredTransform
。对于某些源视频,这个 属性 似乎有一个错误的值,并且视频在结果中出现偏移或全黑。我该如何解决这个问题?
preferredTransform
是 CGAffineTransform
。属性 a
、b
、c
、d
是反射矩阵和旋转矩阵的串联,属性 tx
和 ty
描述了平移.在我观察到 preferredTransform
不正确的所有情况下,reflection/rotation 部分似乎是正确的,只有翻译部分包含错误的值。一个可靠的修复似乎是检查 a
、b
、c
、d
(总共八个案例,每个对应 UIImageOrientation
中的一个案例)和相应地更新 tx
和 ty
:
extension AVAssetTrack {
var fixedPreferredTransform: CGAffineTransform {
var t = preferredTransform
switch(t.a, t.b, t.c, t.d) {
case (1, 0, 0, 1):
t.tx = 0
t.ty = 0
case (1, 0, 0, -1):
t.tx = 0
t.ty = naturalSize.height
case (-1, 0, 0, 1):
t.tx = naturalSize.width
t.ty = 0
case (-1, 0, 0, -1):
t.tx = naturalSize.width
t.ty = naturalSize.height
case (0, -1, 1, 0):
t.tx = 0
t.ty = naturalSize.width
case (0, 1, -1, 0):
t.tx = naturalSize.height
t.ty = 0
case (0, 1, 1, 0):
t.tx = 0
t.ty = 0
case (0, -1, -1, 0):
t.tx = naturalSize.height
t.ty = naturalSize.width
default:
break
}
return t
}
}
我认为我最终做了一些更稳健的事情,我根据最终的结果取消了转换:
auto naturalFrame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
auto preferredFrame = CGRectApplyAffineTransform(naturalFrame, preferredTransform);
preferredTransform.tx -= preferredFrame.origin.x;
preferredTransform.ty -= preferredFrame.origin.y;
请注意,您不能只对 (0, 0)
应用变换,因为 CGRect.origin
会考虑翻转等因素。