国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android高仿抖音照片電影功能的實現代碼

2019-10-21 21:38:46
字體:
來源:轉載
供稿:網友

PhotoMovie (https://github.com/yellowcath/PhotoMovie) 可輕松實現類似抖音、微視、美拍的照片電影功能。

效果如下

濾鏡效果

Android,仿抖音,照片電影,代碼

轉場效果

Android,仿抖音,照片電影,代碼

使用

首先在項目根目錄的build.gradle文件里添加maven庫

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

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

dependencies {  compile 'com.github.yellowcath:PhotoMovie:1.5.0'}

基本用法

可參照 DemoPresenter

//添加圖片    List<PhotoData> photoDataList = new LinkedList<PhotoData>();    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<FitCenterScaleSegment, FitCenterScaleSegment> {  /**   * 縮放動畫范圍   */  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<MovieSegment> 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正常播放即可,效果如下

Android,仿抖音,照片電影,代碼

擴展濾鏡

目前內置了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值,從而實現各種濾鏡效果

Android,仿抖音,照片電影,代碼

lut(原圖)

Android,仿抖音,照片電影,代碼

lut_2.jpg

Android,仿抖音,照片電影,代碼

原圖

Android,仿抖音,照片電影,代碼

濾鏡效果圖

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 進行合成

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿拉善右旗| 贺州市| 泸西县| 墨竹工卡县| 高陵县| 闻喜县| 正定县| 本溪| 亳州市| 社会| 玉屏| 镶黄旗| 磐安县| 中山市| 翁源县| 开远市| 怀化市| 通州市| 韩城市| 吉安县| 武威市| 肃宁县| 大新县| 方山县| 咸宁市| 疏附县| 克东县| 甘肃省| 江川县| 西林县| 和田县| 腾冲县| 北流市| 镇平县| 泰兴市| 长治县| 郯城县| 景洪市| 开江县| 鄂温| 五原县|