摘要: 之前写过一篇 Android YUV图像转换算法和检测工具,里面实现了YUV420的四种格式的相互转换,和与RGB之间的转换。因为是直接用CPU计算的,所以对CPU有一定的消耗和占用。这里我们用OpenGL实现GPU转换。 我们用相机作为YUV420图像输入,上一篇 Android OpenGLES 阅读全文
posted @ 2022-07-18 18:06 rome753 阅读(930) 评论(0) 推荐(0)
摘要: 在看Box2D游戏引擎时,发现了一个很有意思的液体引擎 LiquidFun ,它是Box2D的扩展。给Box2D加上了粒子系统,并且粒子能实现液体的特性。 LiquidFun Github是一个Google的开源项目,LiquidFun官网里面有很多有趣的演示和很多资料,包括它的原理PPT讲解:它其 阅读全文
posted @ 2022-07-18 18:06 rome753 阅读(487) 评论(0) 推荐(0)
摘要: 小米手机播放音乐时锁屏页面可以设置音频可视化效果,这是用OpenGL绘制出来的,我们来实现一下。 首先简单分析一下原理: 图形的每一行代表一个声音片段,它就是一个一维数组,按照数值大小绘制不同的高度,就形成了一条“山脉”;获取到下一个声音片段后,将它绘制到下面一行,然后画面整体向上滚动就可以了。整体 阅读全文
posted @ 2022-07-18 18:05 rome753 阅读(827) 评论(0) 推荐(0)
摘要: 普通的OpenGL绘图时是绘制到当前帧上面,由于GL环境跟当前屏幕进行了关联,也就直接绘制到屏幕了。这样有两个问题:1. 如果有的帧计算得快,有的计算得慢,而屏幕刷新率是固定的,就会拖慢整体帧率;2. 在着色器里面只能处理当前位置的点,没办法处理当前点跟其他点的关系。 如果将OpenGL计算后的帧缓 阅读全文
posted @ 2022-07-18 18:05 rome753 阅读(437) 评论(0) 推荐(0)
摘要: https://github.com/android/media-samples 安卓官方的视频解码器示例 球形视频在全景视频、VR等领域有应用,原理是:解码视频获取每一帧图像,将图像用OpenGL渲染成球形展示出来。下面实现一个简单的Demo,分为三步:展示球体、解码视频、播放球形视频。 1 球体 阅读全文
posted @ 2022-07-18 18:04 rome753 阅读(546) 评论(0) 推荐(0)
摘要: OpenGL绘图一般是在主内存创建数据,计算后传给GPU内存,如果数据是频繁变化的,那么每一帧都要将数据用glBufferSubData方法复制到GPU。其实主内存数据可能是在一个固定的数组里,却要将这个数组反复复制到GPU。如果这个数组能放进GPU,在CPU计算完通知GPU刷新,就省去了复制的操作 阅读全文
posted @ 2022-07-18 18:04 rome753 阅读(229) 评论(0) 推荐(0)
摘要: 在B站上偶然看到一个这样的鱼群模拟的视频,很有意思。大自然很多东西都是类似分形、群体涌现的模式。我们可以用OpenGL简单地模拟一下,先实现一个二维模型,再尝试扩展到三维。 相关资料: https://blog.csdn.net/liweizhao/article/details/82106886 阅读全文
posted @ 2022-07-18 18:03 rome753 阅读(171) 评论(0) 推荐(0)
摘要: https://www.jianshu.com/p/0b66c00d7073 iOS 计算和读取的例子 https://wiki.jikexueyuan.com/project/modern-opengl-tutorial/tutorial28.html PC上解释比较清晰的粒子系统 https:/ 阅读全文
posted @ 2022-07-18 18:03 rome753 阅读(369) 评论(0) 推荐(0)
摘要: https://developer.arm.com/documentation/100587/0100/compute-shaders/compute-shaders-example ARM官方文档里的简单计算Demo https://blog.csdn.net/koibiki/article/de 阅读全文
posted @ 2022-07-18 18:02 rome753 阅读(235) 评论(0) 推荐(0)
摘要: 几年前写了一篇Android SurfaceView 多线程绘图,多线程计算分形图案绘制到屏幕上,这种并行运算更适合用GPU处理。目前手机GPU有几百乃至上千个ALU运算单元,简单地说,相当于一个几百核的处理器,那么处理速度也就比CPU开启多线程快多了。 那么我们用OpenGL来实现一下,效果如下: 阅读全文
posted @ 2022-07-18 18:02 rome753 阅读(504) 评论(0) 推荐(0)
摘要: 相机处理是OpenGL一个重要的应用场景,因为OpenGL的主要工作是处理图像,而相机每秒生成几十帧图像,用GPU来处理再合适不过了。 至于Android CameraX和OpenGL的结合使用,网上有不少教程了,然而它们都有一个特点,就是给两者增加了不必要的耦合。由于两者本身架构都设计得非常好,实 阅读全文
posted @ 2022-07-18 18:01 rome753 阅读(939) 评论(0) 推荐(0)
摘要: WebRTC安卓端没有官方教程,甚至连API文档都没有。这是一件奇怪的事,毕竟WebRTC是Google开发的。目前官方文档和Demo都只有web端的,虽然写得简单易懂,整体用法也和安卓端相同,但是具体细节还是有巨大的差异。 当然,仔细找Google和Github上还是能找到一些不错的教程,我这里将 阅读全文
posted @ 2022-07-18 18:01 rome753 阅读(1088) 评论(0) 推荐(0)
摘要: 1. 格式说明 在安卓开发的一些场景,比如操作相机输出、视频编解码中会用到YUV图像格式。YUV中最常用的是YUV420格式,YUV420就是每4个Y分量共用一个U分量和一个V分量。 YUV420分为4种: I420: YYYYYYYY UU VV YV12:YYYYYYYY VV UU NV12: 阅读全文
posted @ 2022-07-18 18:00 rome753 阅读(1377) 评论(0) 推荐(0)
摘要: 很早就看到过这种场景,用字符来展示图片甚至播放视频,可以说是黑客炫(zhuang)技(b)神器。当然有了一定的技术之后,就明白其实实现挺简单。 相机预览 首先是相机预览的实现,因为不是这里的重点,所以直接在Github上找到成熟的代码。Google官方的Demo当然是最好的: https://git 阅读全文
posted @ 2022-07-18 17:59 rome753 阅读(129) 评论(0) 推荐(0)
摘要: 上一篇完成了两个人在同一个手机中的模拟连接, 这一篇在此基础上给两个手机建立真正的连接. 这就需要一个信令服务器, 其实就是用来给双方交换信息, 并不需要对信息进行处理. 因此服务器和信息的数据格式都可以自己选择, 这里用官方Demo提供的Nodejs服务器, 用soket.io建立连接. 信令服务 阅读全文
posted @ 2022-07-18 17:57 rome753 阅读(655) 评论(0) 推荐(0)
摘要: 在上一篇中完成了WebRTC最基本的使用--相机的使用. 这一篇将介绍WebRTC中最核心的概念PeerConnection , 给同一手机中的前后摄像头建立虚拟的连接, 相互传输画面. PeerConnection PeerConnection也就是Peer-to-Peer connection( 阅读全文
posted @ 2022-07-18 17:56 rome753 阅读(570) 评论(0) 推荐(0)
摘要: Android录制视频有多种方法:MediaRecorder, MediaProjection, MediaMuxer, OpenGL等,每种方法都有其应用场景。 这里介绍的是用MediaCodec + MediaMuxer录制视频,这种方式是将音频流和视频流用MediaCodec编码,然后用Med 阅读全文
posted @ 2022-07-18 17:54 rome753 阅读(913) 评论(0) 推荐(0)
摘要: 词云(WordCloud)是分析数据时一项有趣的展示方式, 它将数据中的关键词按权重设置不同的大小, 放置成一定的形状(比如圆形). 它包括关键词的统计提取和放置, 这里在安卓端实现一个放置词云的View. Google一下word cloud algorithm词云算法, 这里有介绍 https: 阅读全文
posted @ 2022-07-18 17:53 rome753 阅读(191) 评论(0) 推荐(0)
摘要: 多人视频有三种理论方案, 如下图所示, 从左到右分别是Mesh,SFU,MCU. Mesh 网格, 每个人都跟其他人单独建立连接. 4个人的情况下, 每个人建立3个连接, 也就是3个上传流和3个下载流. 此方案对客户端网络和计算能力要求最高, 对服务端没有特别要求. SFU(Selective Fo 阅读全文
posted @ 2022-07-18 17:53 rome753 阅读(403) 评论(0) 推荐(0)
摘要: 最近下了一款小众APP,功能实用,界面简洁,然而用了几分钟页面下方竟然弹出了小窗口广告!并且每分钟自动更新!!耗电、耗流量、占屏幕空间、闪烁吸引眼球、不小心还会误触,这种广告方式是本强迫症患者无法容忍的,相信大部分人也会反感,因此常用的那些APP中也几乎没有看到过。从学习的角度出发,本人尝试对这款应 阅读全文
posted @ 2022-07-18 17:52 rome753 阅读(15140) 评论(0) 推荐(1)
摘要: 以前学习过分形几何,很有意思,由简单的数学公式迭代计算得到的分形图形,放大后不会丢失细节。典型的如Mandelbrot图形: 计算方式也不复杂,由f(z) = z^2 + c,迭代计算 z1=f(z0), z2=f(z1), z3=f(z2)...其中z, c都是复数,可以表示为复平面上的一个点,而 阅读全文
posted @ 2022-07-18 17:51 rome753 阅读(584) 评论(0) 推荐(0)
摘要: 高斯模糊是用得最广泛的图像模糊算法,它的原理很简单,对每个点计算它周围其他点的平均色值,设置到该点上,就是模糊后的图。取周围其他点的范围称为模糊半径,模糊半径越大也就越模糊。高斯模糊算法网上很多,可以参考这个: http://www.quasimondo.com/StackBlurForCanvas 阅读全文
posted @ 2022-07-18 17:51 rome753 阅读(199) 评论(0) 推荐(0)
摘要: UIViewController 的生命周期有个奇怪的地方,就是有页面加载的方法 viewDidLoad(),却没有页面销毁的方法。只有一个 deinit{},它代表的是对象的销毁。然而关闭页面时,对象不一定会销毁。 如果在deinit{}里面去释放资源,资源没释放导致内存泄漏,那么deinit{} 阅读全文
posted @ 2022-07-18 17:50 rome753 阅读(1025) 评论(0) 推荐(0)
摘要: 值类型在传递和赋值时将进行复制,而引用类型只会使用引用对象。 Swift中定义的很多类型都是值类型,如struct、enum以及所有的内建类型(Int、Bool、String、Array、Dictionary)都是值类型。class为引用类型。 以最常用的数组为例 值传递 A,B两个类各有一个Arr 阅读全文
posted @ 2022-07-18 17:49 rome753 阅读(159) 评论(0) 推荐(0)
摘要: 新建一个iOS工程,系统会自动创建ViewController,并在Main.storyboard中引用它作为主页面。这是一个基本的ViewController,如果要改成带导航栏的UINavigationController或者其他的,就得更换。网上搜了一下,资料很乱,改的地方很多,而且有的生效, 阅读全文
posted @ 2022-07-18 17:49 rome753 阅读(844) 评论(0) 推荐(0)
摘要: offsetBy() 是移动矩形位置,大小不变。dx 和 dy 表示origin移动距离。 insetBy() 是缩小或放大矩形,中心点不变。dx 和 dy 表示矩形四边同时向中心点移动的距离。origin移动距离也是 dx 和 dy,宽高的变化是 -2dx 和 -2dy。 (lldb) po f 阅读全文
posted @ 2022-07-18 17:48 rome753 阅读(304) 评论(0) 推荐(0)
摘要: 列表是最常用的UI组件,iOS中列表分为UITableView和UICollectionView。UITableView是普通的纵向滑动列表,UICollectionView相当于前者的升级版,可以实现横向滑动等复杂的布局,定义列表item的样式等。 列表的使用相对麻烦一点,除了要操作控件,还要操作 阅读全文
posted @ 2022-07-18 17:48 rome753 阅读(657) 评论(0) 推荐(0)
摘要: // 直接添加延时任务 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { } // 初始化延时任务 var dispatchWorkItem = DispatchWorkItem { } // 添加延时任务 DispatchQueue.m 阅读全文
posted @ 2022-07-18 17:47 rome753 阅读(799) 评论(0) 推荐(0)
摘要: 当前View里面有两个View,绿色的bigView和红色的smallView,smallView在bigView里面。现在让bigView执行一段移动动画,然后给bigView添加点击事件,发现点击事件无效。 因为iOS动画中的View点击事件无效。 原因是iOS里几乎所有的View动画是都基于l 阅读全文
posted @ 2022-07-18 17:47 rome753 阅读(276) 评论(0) 推荐(0)
摘要: 两个UILabel放在同一行,需要设置它们的抗压缩和抗拉伸属性。 class MyView: UIView { lazy var leftLabel = UILabel() lazy var rightLabel = UILabel() override init(frame: CGRect) { 阅读全文
posted @ 2022-07-18 17:46 rome753 阅读(352) 评论(0) 推荐(0)
摘要: 当前View里面有两个View,绿色的bigView和红色的smallView,smallView在bigView里面。现在要在当前View的touchesBegan方法判断点击位置是否在最里层的smallView里。 有多种方法可以判断。其实它们本质都是一样的,最重要的是转换参考系。 要想判断po 阅读全文
posted @ 2022-07-18 17:46 rome753 阅读(852) 评论(0) 推荐(0)
摘要: 原来用GPUImage实现,采用的这篇博客介绍的方法,但是有两个比较严重的问题: App启动后第一次使用播放器时会造成主线程卡住1~5秒,越老的机型越长,第二次和以后就完全不卡,直到下次启动。这应该是GPUImage某处初始化造成的,我没有找到具体位置。 播放某些视频时,画面中亮白色的位置会出现“过 阅读全文
posted @ 2022-07-18 17:45 rome753 阅读(804) 评论(0) 推荐(0)
摘要: 协议protocol一般用来做回调监听,当多个地方需要添加回调监听时,就要用Set集合来管理,Set中的元素需要实现Hashable方法,而协议protocol是不能实现Hashable方法的,会报如下错误。 Protocol 'MyProtocol' as a type cannot confor 阅读全文
posted @ 2022-07-18 17:45 rome753 阅读(155) 评论(0) 推荐(0)
摘要: 通常使用多语言在Resource里配置Localizable文件,添加需要的语言即可。 使用String的扩展方法如下: 如果需要占位符,%d表示数字,%@表示字符串,用localizedWithArgs方法 func localized() -> String { return NSLocaliz 阅读全文
posted @ 2022-07-18 17:44 rome753 阅读(327) 评论(0) 推荐(0)
摘要: private var bgImageGaussDataDict:[Int:Data] = [:] var guassImageData = bgImageGaussDataDict[gauss] if guassImageData == nil { let image = bgImageOrigi 阅读全文
posted @ 2022-07-18 17:44 rome753 阅读(131) 评论(0) 推荐(0)
摘要: iOS 界面开发最重要的是ViewController和View,ViewController是View的控制器,也就是一般的页面,用来管理页面的生命周期(它相当于安卓里的Activity,两者很像,又有一些差异)。 ViewController的特点是它有好几种。一种最基本的UIViewContr 阅读全文
posted @ 2022-07-18 17:43 rome753 阅读(304) 评论(0) 推荐(0)
摘要: 如果键盘弹起的时候,获得焦点也就是becomeFirstResponder的输入框位置会被键盘挡住,那么系统会自动将输入框所在的整体布局向上移动。这种移动不一定是我们想要的,如果想要更精准的控制,就需要在键盘弹起之前主动移动输入框到键盘上方,这样系统就不会自动移动整体布局了。 keyboardWil 阅读全文
posted @ 2022-07-18 17:43 rome753 阅读(272) 评论(0) 推荐(0)
摘要: let myView = UIView() myView.bounds = CGRect(x: 0, y: 0, width: 300, height: 100) myView.addGradientLayerWithCorner(cornerRadius: 20, lineWidth: 10, c 阅读全文
posted @ 2022-07-18 17:42 rome753 阅读(760) 评论(0) 推荐(0)
摘要: 相比于安卓开发来说,iOS开发中最麻烦的事情就是手动计算高度了。 在UITableView或UICollectionView列表的item、header、footer中,如果列表项的高度不是固定的,那么就需要自己计算实际高度,然后通过tableView(_ tableView: UITableVie 阅读全文
posted @ 2022-07-18 17:42 rome753 阅读(2313) 评论(0) 推荐(0)
摘要: 用 CAShapeLayer 和 UIBezierPath 贝塞尔曲线实现,每次进度变化时,重新初始化一个 CAShapeLayer 添加到当前 UIView 上。 import Foundation import UIKit class CircleProgressView: UIView { / 阅读全文
posted @ 2022-07-18 17:41 rome753 阅读(668) 评论(0) 推荐(0)
摘要: 一般来说,在UIViewController里的UIView使用lazy var,可以确保在只第一次使用时创建。 但是如果在viewDidLoad()前访问这个View,那么这个View就会创建两次,说明Lazy var机制失效了。网上搜了一下,都是说Lazy var在多线程下会失效。然而我打印一下 阅读全文
posted @ 2022-07-18 17:37 rome753 阅读(91) 评论(0) 推荐(0)
摘要: 1 安装OpenCV 因为不需要特别的编译配置,所以我没有用编译安装,直接用brew安装 brew install opencv 中间遇到一次安装sqlite失败,先安装一下sqlite brew install sqlite 再安装opencv就可以了。 安装后目录在/opt/homebrew/C 阅读全文
posted @ 2022-07-18 17:30 rome753 阅读(96) 评论(0) 推荐(0)
摘要: 1 CascadeClassifier 级联分类器人脸识别 有两种:haar级联和lbp级联,我用brew安装的,级联文件在/opt/homebrew/Cellar/opencv/4.5.5_2/share/opencv4/haarcascades里面,haar级联文件大小是900kb左右,lbp级 阅读全文
posted @ 2022-07-18 17:30 rome753 阅读(664) 评论(0) 推荐(0)
摘要: https://trac.ffmpeg.org/wiki/Capture/Desktop 官网教程 mac安装ffmpeg后,用命令行可以录屏。 1 获取mac的视频设备和音频设备 ffmpeg -f avfoundation -list_devices true -i "" 可以看到,视频设备有摄 阅读全文
posted @ 2022-07-18 17:29 rome753 阅读(439) 评论(0) 推荐(0)
摘要: ffmpeg命令行可以很方便地进行rtmp直播推流。 1 安装nginx服务 注意不能直接安装,一定要安装带rtmp模块的,否则会报rtmp找不到的错误。 安装有两种方式,一是自己编译安装,我没有采用;另一种是安装配置好的,用下面这篇教程的方法: https://www.jianshu.com/p/ 阅读全文
posted @ 2022-07-18 17:26 rome753 阅读(541) 评论(0) 推荐(0)
摘要: iOS工程添加OpenCV配置方法如下 https://blog.csdn.net/verybigbug/article/details/113588991 配置好后,就可以在移动端开发OpenCV了。我用的是Swift语言。 1 简单的图片处理 用import opencv2可以直接导入OpenC 阅读全文
posted @ 2022-07-18 17:26 rome753 阅读(514) 评论(0) 推荐(0)
摘要: 最近开始学一下ffmpeg,在电脑上开发和调试是比较方便的,后面也可以移植到移动端。mac上开发c/c++项目有几种方式:Xcode、VSCode和VS,其中:VS社区版和普通版都不支持c/c++语言,安装后你会发现在任何创建工程和添加插件的地方你都找不到c/c++,因为它不支持。VSCode有c/ 阅读全文
posted @ 2022-07-18 17:26 rome753 阅读(326) 评论(0) 推荐(0)