效果如下

滤镜效果

转场效果

使用

首先在项目根目录的build.gradle文件里添加maven库

allprojects {

repositories {

...

maven { url 'https://www.jitpack.io' }

}

}

再在需要用的Module的build.gradle里添加依赖

dependencies {

compile 'com.github.yellowcath:PhotoMovie:1.5.0'

}

基本用法

//添加图片

List photoDataList = new LinkedList();

photoDataList.add(new SimplePhotoData(context,photoPath1,PhotoData.STATE_LOCAL));

...

photoDataList.add(new SimplePhotoData(context,photoPathN,PhotoData.STATE_LOCAL));

//生成图片源

PhotoSource photoSource = new PhotoSource(photoDataList);

//生成照片电影(使用预定义的水平转场动画)

PhotoMovie photoMovie = PhotoMovieFactory.generatePhotoMovie(photoSource, PhotoMovieFactory.PhotoMovieType.HORIZONTAL_TRANS);

//生成负责绘制电影内容的MovieRenderer

MovieRenderer movieRenderer = new GLTextureMovieRender(glTextureView);

/**

* OR MovieRenderer movieRenderer = new GLSurfaceMovieRenderer(glSurfaceView);

*/

//照片电影播放器

PhotoMoviePlayer photoMoviePlayer = new PhotoMoviePlayer(context);

photoMoviePlayer.setMovieRenderer(mMovieRenderer);

photoMoviePlayer.setMovieListener(...);

photoMoviePlayer.setLoop(true);

photoMoviePlayer.setOnPreparedListener(new PhotoMoviePlayer.OnPreparedListener() {

@Override

public void onPreparing(PhotoMoviePlayer moviePlayer, float progress) {

}

@Override

public void onPrepared(PhotoMoviePlayer moviePlayer, int prepared, int total) {

mPhotoMoviePlayer.start();

}

@Override

public void onError(PhotoMoviePlayer moviePlayer) {

}

});

photoMoviePlayer.prepare();

轻松扩展

PhotoMovie使用模块化的设计,每个部分都可以自定义然后替换,

MovieSegment:电影片段,每个电影片段都有特定的时长,在这段时间之内以特定的方式播放图片,例如ScaleSegment会对图片做缩放动画、EndGaussianBlurSegment会对图片做从清晰到模糊的高斯模糊动画

PhotoMovie:核心类,代表照片电影本身,由图片源(PhotoSource)和若干电影片段(MovieSegment)组成一个完整的照片电影,图片通过PhotoAllocator分配给MovieSegment

MovieLayer:为MovieSegment扩展绘制多层特效的功能,例如SubtitleLayer提供字幕展示

IMovieFilter:为整个照片电影提供滤镜

MovieRenderer:负责把照片电影渲染到指定的输出界面,例如TextureView(GLTextureMovieRender)、GLSurfaceView(GLSurfaceMovieRenderer)

PhotoMoviePlayer:提供类似MediaPlayer的接口,负责播放照片电影,播放进度由IMovieTimer控制

扩展电影类型

目前内置了6种类型,后两种即是抖音的左右切换和上下切换,Thaw和WINDOW仿自美拍

public enum PhotoMovieType {

THAW, //融雪

SCALE, //缩放

SCALE_TRANS, //缩放 & 平移

WINDOW, //窗扉

HORIZONTAL_TRANS,//横向平移

VERTICAL_TRANS//纵向平移

}

这里以微视的渐变特效为例展示如何扩展

分析得出,渐变特效首先图片居中放置,然后全程做一个微弱的放大动画,后半部分同时透明度变化消失

可见需要两个不同的片段类型

首先创建FitCenterScaleSegment,继承FitCenterSegment,实现单张图片的放大动画

public class FitCenterScaleSegment extends FitCenterSegment {

/**

* 缩放动画范围

*/

private float mScaleFrom;

private float mScaleTo;

private float mProgress;

/**

* @param duration 片段时长

* @param scaleFrom 缩放范围

* @param scaleTo 缩放范围

*/

public FitCenterScaleSegment(int duration, float scaleFrom, float scaleTo) {

super(duration);

mScaleFrom = scaleFrom;

mScaleTo = scaleTo;

}

@Override

protected void onDataPrepared() {

super.onDataPrepared();

}

@Override

public void drawFrame(GLESCanvas canvas, float segmentProgress) {

mProgress = segmentProgress;

if (!mDataPrepared) {

return;

}

drawBackground(canvas);

float scale = mScaleFrom + (mScaleTo - mScaleFrom) * mProgress;

//FitCenterSegment已经具有缩放能力,这里传缩放值即可

drawContent(canvas, scale);

}

//提升这两个函数的访问权限,供转场时使用

@Override

public void drawContent(GLESCanvas canvas, float scale) {

super.drawContent(canvas, scale);

}

@Override

public void drawBackground(GLESCanvas canvas) {

super.drawBackground(canvas);

}

}

然后创建转场片段GradientTransferSegment,其父类TransitionSegment同时持有上一个与下一个片段,可以在其基础上实现任意转场功能

public class GradientTransferSegment extends TransitionSegment {

/**

* 缩放动画范围

*/

private float mPreScaleFrom;

private float mPreScaleTo;

private float mNextScaleFrom;

private float mNextScaleTo;

public GradientTransferSegment(int duration,

float preScaleFrom, float preScaleTo,

float nextScaleFrom, float nextScaleTo) {

mPreScaleFrom = preScaleFrom;

mPreScaleTo = preScaleTo;

mNextScaleFrom = nextScaleFrom;

mNextScaleTo = nextScaleTo;

setDuration(duration);

}

@Override

protected void onDataPrepared() {

}

@Override

public void drawFrame(GLESCanvas canvas, float segmentProgress) {

//下一个片段开始放大

float nextScale = mNextScaleFrom + (mNextScaleTo - mNextScaleFrom) * segmentProgress;

mNextSegment.drawContent(canvas, nextScale);

//上一个片段继续放大同时变透明

float preScale = mPreScaleFrom + (mPreScaleTo - mPreScaleFrom) * segmentProgress;

float alpha = 1 - segmentProgress;

mPreSegment.drawBackground(canvas);

canvas.save();

canvas.setAlpha(alpha);

mPreSegment.drawContent(canvas, preScale);

canvas.restore();

}

创建照片电影

private static PhotoMovie initGradientPhotoMovie(PhotoSource photoSource) {

List segmentList = new ArrayList<>(photoSource.size());

for (int i = 0; i < photoSource.size(); i++) {

if (i == 0) {

segmentList.add(new FitCenterScaleSegment(1600, 1f, 1.1f));

} else {

segmentList.add(new FitCenterScaleSegment(1600, 1.05f, 1.1f));

}

if (i < photoSource.size() - 1) {

segmentList.add(new GradientTransferSegment(800, 1.1f, 1.15f, 1.0f, 1.05f));

}

}

return new PhotoMovie(photoSource, segmentList);

}

然后将这个PhotoMovie正常播放即可,效果如下

扩展滤镜

目前内置了9个滤镜

public enum FilterType {

NONE,

CAMEO,//浮雕

GRAY,//黑白

KUWAHARA,//水彩

SNOW,//飘雪(动态)

LUT1,

LUT2,

LUT3,

LUT4,

LUT5,

}

先看IMovieFilter

public interface IMovieFilter {

void doFilter(PhotoMovie photoMovie,int elapsedTime, FboTexture inputTexture, FboTexture outputTexture);

void release();

}

外部会提供一个输入纹理,然后由IMovieFilter处理之后绘制到输出纹理上,即实现了滤镜效果

BaseMovieFilter已经实现了基本的输入输出流程,例如要做最基本的黑白滤镜,只需更换FRAGMENT_SHADER即可

public class GrayMovieFilter extends BaseMovieFilter {

protected static final String FRAGMENT_SHADER = "" +

"varying highp vec2 textureCoordinate;\n" +

" \n" +

"uniform sampler2D inputImageTexture;\n" +

" \n" +

"void main()\n" +

"{\n" +

" mediump vec4 color = texture2D(inputImageTexture, textureCoordinate);\n" +

" mediump float gray = color.r*0.3+color.g*0.59+color.b*0.11;\n"+

" gl_FragColor = vec4(gray,gray,gray,1.0);\n"+

"}";

public GrayMovieFilter(){

super(VERTEX_SHADER,FRAGMENT_SHADER);

}

}

同时PhotoMovie提供了对Lut滤镜的支持

Lut其实就是Lookup Table(颜色查找表),根据原图的RGB值去相应的lut图里面查找对应转换后的RGB值,从而实现各种滤镜效果

lut(原图)

lut_2.jpg

原图

滤镜效果图

public class LutMovieFilter extends TwoTextureMovieFilter {

public LutMovieFilter(Bitmap lutBitmap){

super(loadShaderFromAssets("shader/two_vertex.glsl"),loadShaderFromAssets("shader/lut.glsl"));

setBitmap(lutBitmap);

}

}

在LutMovieFilter的构造函数传入上面表格里的lut图,即可实现相应的滤镜效果,前面提到的黑白滤镜也可用这个方式实现

录制功能

GLMovieRecorder提供了将照片电影录制为mp4的功能

可参照 DemoPresenter的saveVideo()函数

GLMovieRecorder recorder = new GLMovieRecorder();

recorder.configOutput(width, height(), bitrate,frameRate,iFrameInterval, outputPath);

recorder.setDataSource(movieRenderer);

recorder.startRecord(new GLMovieRecorder.OnRecordListener() {

@Override

public void onRecordFinish(boolean success) {

......

}

@Override

public void onRecordProgress(int recordedDuration, int totalDuration) {

......

}

});

背景音乐

mPhotoMoviePlayer.setMusic(context, mMusicUri);

PhotoMovie只提供了播放背景音乐的功能,录制完成之后需自行合成,Demo里使用了

VideoProcessor.mixAudioTrack(context, videPath, audioPath,outputPath, null, null, 0,100, 1f, 1f);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

抖音自拍特效如何java实现_Android高仿抖音照片电影功能的实现代码相关推荐

  1. 原生Java高仿抖音短视频APP双端源码

    简介: 从别的网站199购买的原生Java高仿抖音短视频APP双端源码,免费给大家~ 源码未测试,java开发,上手有难度,小白童鞋请勿瞎捣鼓. 安卓语言是:android stdio 苹果语言是:O ...

  2. Android高仿抖音照片电影功能

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 PhotoMovie(https://github.com/yellowcath/PhotoMovie)可轻松实现类似抖音.微视.美 ...

  3. 仿抖音短视频源码,高仿抖音双击点赞效果之双击的问题

    仿抖音短视频源码中,实现仿抖音的双击点赞效果,相关代码如下: public class MyView extends View {private GestureDetector gestureDete ...

  4. Making video with your pictures(高仿抖音照片电影功能)

    PhotoMovie 项目地址:yellowcath/PhotoMovie  简介:Making video with your pictures(高仿抖音照片电影功能) 更多:作者   提 Bug ...

  5. Android特效专辑(十二)——仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View...

    Android特效专辑(十二)--仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View 先来看看这个效果 这是我的在Only上添加的效果,说实话,Only现在都还只是半成品,台面都上不了,怪自己技术 ...

  6. Android特效专辑(十二)——仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View

    Android特效专辑(十二)--仿支付宝咻一咻功能实现波纹扩散特效,精细小巧的View 先来看看这个效果 这是我的在Only上添加的效果,说实话,Only现在都还只是半成品,台面都上不了,怪自己技术 ...

  7. html高仿抖音,最新高仿抖音短视频APP应用原生双端源码(java源生源码)

    [原生抖音短视频]19年11月最新高仿抖音短视频APP应用原生双端源码[java原生源码] 安卓语言是:android stdio 苹果语言是:OC 环境php5.6 sql5.5 伪静态设置thin ...

  8. android 动态壁纸仿抖音,Android高仿抖音照片电影功能

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 滤镜效果 filter.gif 转场效果 transfer.gif 基本用法 //添加图片 List photoDataList = ...

  9. 基于android的高仿抖音,Android仿抖音列表效果

    本文实例为大家分享了Android仿抖音列表效果的具体代码,供大家参考,具体内容如下 当下抖音非常火热,是不是也很心动做一个类似的app吗? 那我们就用RecyclerView实现这个功能吧,关于内存 ...

最新文章

  1. QT的QMutableLinkedListIterator类的使用
  2. 微型计算机技术第三版第三章答案,第3章微机组装技术作业(答案)
  3. EF Core的一个紧急bug,我这样修改
  4. swift中没有selectall的解决
  5. 华为交换机eth口作用_华为交换机口如何绑定端口号
  6. mysql存储过程的一个小例子
  7. 51nod 1050 循环数组最大子段和【环形DP/最大子段和/正难则反】
  8. SQL Server 透视与逆透视转换解析
  9. 手把手教你迁移微信小程序到 QQ 浏览器
  10. 20145322何志威 Exp8 Web基础
  11. Android发送edp服务器,Android开发之基于OneNET平台的EDP传输协议的使用
  12. Unity中的物体渲染顺序
  13. python 两点曲线_Python自学教程| 3万字详解每个重要知识点(内附视频)
  14. ubuntu20 安装TP Link TL-WDN5200无线网卡驱动
  15. 文件浏览器ftp服务器,es文件浏览器查看ftp服务器
  16. ubuntu18.04安装搜狗输入法
  17. 文本生成任务常见评估指标
  18. 访问WebLogic For AIX忽快忽慢的困惑——续篇
  19. 点如何在平面设计中应用
  20. 如何给多个Word文档创建一个有连续页码的目录

热门文章

  1. 关于区块链你了解多少
  2. HostEase虚拟主机转战中国市场 以品质突破国内商家价格围攻
  3. Eagleware.Genesys.Premier.v7.52_Win9xNT2K 1CD
  4. [统计学笔记] (四)数据分布的数字特征
  5. 如何更新您的Apple AirPods
  6. Linux系统中修改用户名的两种方案整理
  7. js读取excel的值
  8. 高数_证明_多元函数极值的充分条件
  9. 什么是SpringIOC?如何理解SpringIOC?
  10. OSSH免费版华为Portal对接华为9303交换机示例说明