前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >坐标系统仿射变换函数使用总结

坐标系统仿射变换函数使用总结

原创
作者头像
SheltonWan
修改2019-06-12 11:28:14
1.4K0
修改2019-06-12 11:28:14
举报
文章被收录于专栏:程序员读书笔记

默认情况下,用iphone录制的视频,如果要在mac上播放,可能需要将其翻转。

首先理清一下iOS与Mac坐标系统:

iOS的UIKit坐标系统是已左上角为坐标原点,向右为X轴正向,向下为Y轴正向。

Mac的AppKit坐标系统是已左下角为坐标原点,向右为X轴正向,向上为Y轴正向。

CoreGraphic坐标系统与AppKit坐标系统一致。

AVFoundation坐标系统与UIKit坐标系统一致。

应用AVFoundation处理视频,初始状态下,屏幕原点坐标在左上角,其坐标图如下:

上图阴影部分代表屏幕窗口,阴影上虚线表示录制视频覆盖位置,正常情况下如果将视频尺寸设置为窗口尺寸,实际播放只会显示阴影长方形和虚线长方形重复的部分图像而已。

正常思路,让视频翻转90度,即可满足视频横屏需求,我们尝试执行如下代码:

CGAffineTransform transform = CGAffineTransformIdentity;//单位矩阵

transform = CGAffineTransformRotate(transform, M_PI/2); //矩阵翻转90度

将上面仿射变换应用到视频去,运行起来发现整个屏幕黑屏,什么都看不见了。究其原因是我们忽视了视频翻转点,实际翻转效果如下图:

默认情况下,我们执行翻转90度,是绕着原点(0,0)顺时针翻转90度,虽然视频翻成了横屏,但是整个图像却跑到屏幕左边去了,我们可以通过将图像进行平移到屏幕区,已达到我们想要的效果。

假如:

CGSize naturalSize = {1080,1920};//视频自然尺寸

CGSize renderSize = {1920,1080}; //播放尺寸

如果不加思索,我们很容易写出下面代码:

transform =CGAffineTransformTranslate(transform,1920,0);

我们寄希望得到我们想要的图像,结果发现整个屏幕还是黑的,原因是我们没注意到,在之前翻转90的时候,其实,其坐标系也可以理解成按顺时针翻转了90度了,此时横向方向实际上y坐标,往左为正。而垂直方向才是x坐标,往下为正,注意上图的坐标。

因此我们所要做的平移代码得写成如下:

transform =CGAffineTransformTranslate(transform,0,-1920);

注意了,仿射变换执行的顺序是不能改变的,如果我们调换CGAffineTransformTranslate与CGAffineTransformRotate的顺序,其执行结果是不同的。

究其原因是参考坐标系变换了,如果我们要先执行平移再翻转,代码就得写成如下:

CGAffineTransform transform = CGAffineTransformIdentity;//单位矩阵

transform =CGAffineTransformTranslate(transform,1920,0);

transform = CGAffineTransformRotate(transform, M_PI/2); //矩阵翻转90度

我们来分析一下,参考第一张图,我们先将垂直方向的视频往X坐标轴平移1920,然后再顺时针翻转90度,此时翻转是绕着(1920,0)这个点来翻转的。此时翻转后得视频就刚好横屏在实际屏幕位置。

我们也可以这样来理解,假如屏幕坐标系不变,往左方向为X轴正方向,往下为Y轴正方向。当我们往X轴平移1920时,我们的参考坐标系原点就平移到屏幕坐标(1920,0)这个位置上,随后翻转90度,就是绕着参考坐标系原点顺时针旋转90度。翻转后,参考坐标系将发生改变,此时参考坐标系原点相对屏幕坐标(1920,0)不变,但是参考坐标系改变为往左为Y轴正方向,,而往下为X正方向了。

此时,我们看到我们想要的整个视频,但是我们的参考坐标系不再跟屏幕坐标系相等了,参考坐标系原点已经在右上角了,而往左为Y轴正方向,往下为X轴正方向。

因此,如果此时我们还想将视频进行180度顺时针翻转,不能简简单单的执行下面代码:

transform = CGAffineTransformRotate(transform, M_PI);

我们要注意在翻转时,参考坐标系原点在哪里。这代码执行结果就是,视频被绕着屏幕右上角顺时针旋转了180度,跑到屏幕右上方,完全移除屏幕去了,结果就是黑屏。

这时候我们需要将视频平移回来才能得到我们想要的结果。此时,我们的参考坐标系已经变为,往上为Y轴正方向,往左为X正方向,入下图:

transform =CGAffineTransformTranslate(transform,-1920,1080);

执行上面平移,视频就回到阴影位置,则屏幕区域,得到我们想要的结果了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档