利用 OpenGL ES 给视频播放器和相机做个字符画滤镜

该原创文章首发于微信公众号:字节流动

最后不少朋友问,“OpenGL ES 入门后怎么学习写一些滤镜?”,“怎么学习 shader ?”。

最近请教了一些大佬,他们一致认为正确的做法就是“去模仿”。先去模仿别人的滤镜怎么实现的,比如观察抖音的一些简单的滤镜,然后自己琢磨去实现一个。

当然,最有效率的方法是研究一些相关的开源项目,比如大名鼎鼎的 android-gpuimage 项目,该项目基本上实现了各种常见滤镜,上手容易,学习 shader 、熟悉 GLSL 或者对 OpenGL 滤镜感兴趣的同学,可以研究下。

顺便说下,最近看了一个项目叫 android-gpuimage-plus ,主要讲是 Native 层实现的滤镜,有一些比较不错的思路可以参考下。

之前有一位朋友发了一副表情画滤镜的效果图,就是利用不同的表情去替换不同的像素,生成一副由表情组成的图像。表情画滤镜的原理其实跟字符画相同,只是字符换成了表情。

由于那副效果图不方便展示,这里就介绍下字符画的实现原理,利用一个 shader 来实现字符画效果。

字符画滤镜原理

字符画滤镜其实跟 LUT 滤镜是同一个原理,本质上就是查表,像素替换。

实现字符画滤镜,首先想到的法子是,对图像进行逐像素替换成字符(一个字符实际上是由多个像素组成的小图片)。

逐像素替换会有两个问题

  1. 一个像素有 RGB 2
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个基本的视频播放器的头文件和源代码,使用了Qt、FFmpeg和OpenGL: 头文件 VideoPlayer.h: ```c++ #ifndef VIDEOPLAYER_H #define VIDEOPLAYER_H #include <QtWidgets/QMainWindow> #include <QtAV/AVPlayer.h> #include <QtAV/VideoOutput.h> #include <QOpenGLWidget> class VideoPlayer : public QMainWindow { Q_OBJECT public: VideoPlayer(QWidget *parent = nullptr); ~VideoPlayer(); private slots: void on_playButton_clicked(); void on_pauseButton_clicked(); void on_positionChanged(qint64 position); private: Ui::VideoPlayerClass ui; QtAV::AVPlayer *m_player; QtAV::VideoOutput *m_videoOutput; QOpenGLWidget *m_glWidget; QSlider *m_positionSlider; }; #endif // VIDEOPLAYER_H ``` 源文件 VideoPlayer.cpp: ```c++ #include "VideoPlayer.h" #include "ui_VideoPlayer.h" VideoPlayer::VideoPlayer(QWidget *parent) : QMainWindow(parent) , ui(new Ui::VideoPlayerClass) { ui->setupUi(this); // 创建AVPlayer m_player = new QtAV::AVPlayer(this); // 创建VideoOutput m_videoOutput = new QtAV::VideoOutput(this); m_glWidget = new QOpenGLWidget(this); // 创建QOpenGLWidget m_videoOutput->setOutputWidget(m_glWidget); // 设置播放器的输出设备 m_player->setRenderer(m_videoOutput); // 连接信号和槽 connect(m_player, SIGNAL(positionChanged(qint64)), this, SLOT(on_positionChanged(qint64))); // 设置进度条的范围 m_positionSlider = new QSlider(Qt::Horizontal); m_positionSlider->setRange(0, 0); // 将控件添加到窗口中 ui->videoLayout->addWidget(m_glWidget); ui->controlLayout->addWidget(m_positionSlider); } VideoPlayer::~VideoPlayer() { delete ui; } void VideoPlayer::on_playButton_clicked() { m_player->play(); } void VideoPlayer::on_pauseButton_clicked() { m_player->pause(); } void VideoPlayer::on_positionChanged(qint64 position) { m_positionSlider->setRange(0, m_player->duration()); m_positionSlider->setValue(position); } ``` 以上代码只是一个简单的框架,你需要根据自己的需进行修改和扩展。同时,你需要在.pro文件中添加以下依赖: ``` QT += widgets QT += opengl LIBS += -lQtAV LIBS += -lavcodec LIBS += -lavformat LIBS += -lavutil LIBS += -lswscale ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

字节流动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值