=uEnd){\n" +
30 | " uAlpha = 1.0;\n" +
31 | " } else{\n" +
32 | " uAlpha = (y - uStart) / (uEnd - uStart);\n" +
33 | " }\n" +
34 | " } else if(uStart == uEnd){\n" +
35 | " uAlpha = 1.0;\n" +
36 | " } else{\n" +
37 | " if(y >= uStart){\n" +
38 | " uAlpha = 0.0;\n" +
39 | " } else if(y <=uEnd){\n" +
40 | " uAlpha = 1.0;\n" +
41 | " } else{\n" +
42 | " uAlpha = (y - uStart) / (uEnd - uStart);\n" +
43 | " } \n" +
44 | " }" +
45 | " gl_FragColor *=uAlpha;\n" +
46 | "}";
47 |
48 |
49 | private int mStartLocation;
50 | private int mEndLocation;
51 |
52 | public AlphaGradientFilter() {
53 | super(VERTEX_SHADER, ALPHA_FRAGMENT_SHADER);
54 | }
55 |
56 | @Override
57 | public void init() {
58 | super.init();
59 | mStartLocation = GLES20.glGetUniformLocation(mProgId, "uStart");
60 | mEndLocation = GLES20.glGetUniformLocation(mProgId, "uEnd");
61 | }
62 |
63 | @Override
64 | public void drawFrame(float progress, int glTextureId, Rect textureRext, RectF srcRect, RectF dstRect) {
65 | float baseY = (srcRect.top - textureRext.top) / textureRext.height();
66 | float scaleY = srcRect.height() / textureRext.height();
67 | mRangeStart = baseY + mRangeStart * scaleY;
68 | mRangeEnd = baseY + mRangeEnd * scaleY;
69 | GLES20.glUniform1f(mStartLocation, mRangeStart);
70 | GLES20.glUniform1f(mEndLocation, mRangeEnd);
71 | super.drawFrame(progress, glTextureId, textureRext, srcRect, dstRect);
72 | }
73 |
74 | @Override
75 | public void setRange(float start, float end) {
76 | super.setRange(start, end);
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/filter/GrayFilter.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.filter;
2 |
3 | /**
4 | * Created by huangwei on 2015/6/23.
5 | */
6 | public class GrayFilter extends MovieFilter {
7 |
8 | protected static final String FRAGMENT_SHADER = "" +
9 | "varying highp vec2 textureCoordinate;\n" +
10 | " \n" +
11 | "uniform sampler2D inputImageTexture;\n" +
12 | " \n" +
13 | "void main()\n" +
14 | "{\n" +
15 | " mediump vec4 color = texture2D(inputImageTexture, textureCoordinate);\n" +
16 | " mediump float gray = color.r*0.3+color.g*0.59+color.b*0.11;\n"+
17 | " gl_FragColor = vec4(gray,gray,gray,1.0);\n"+
18 | "}";
19 |
20 | public GrayFilter() {
21 | super(VERTEX_SHADER,FRAGMENT_SHADER);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/filter/OldMovieFilter.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.filter;
2 |
3 | import android.opengl.GLES20;
4 |
5 | /**
6 | * Created by huangwei on 2015/6/23.
7 | */
8 | public class OldMovieFilter extends MovieFilter {
9 | protected static final String FRAGMENT_SHADER = "precision highp float;\n" +
10 | " varying vec2 textureCoordinate;\n" +
11 | " vec4 coefficient = vec4(0.0,0.5,1.0,0.4); \n" +/* inverted, radius, gradient, brightness. */
12 | " vec4 color = vec4(1.0,1.0,1.0,1.0);\n" +
13 | " vec2 touchPoint = vec2(0.5,0.5);\n" +
14 | " uniform sampler2D inputImageTexture;\n" +
15 | " vec2 resolution = vec2(700.0,1000.0);\n" +
16 | " uniform float uRandom;\n" +
17 | " float dis = 50.0;\n" +
18 | " \n" +
19 | " float getMask(float radius, vec2 pos, vec2 centre)\n" +
20 | " {\n" +
21 | " float rDis = dis * uRandom;\n" +
22 | " float xDis = rDis/resolution.x;\n" +
23 | " float yDis = rDis/resolution.y;\n" +
24 | " float l = 0.0 + rDis;\n" +
25 | " float r = resolution.x - rDis;\n" +
26 | " float b = 0.0 + rDis;\n" +
27 | " float t = resolution.y - rDis;\n" +
28 | " if(pos.x < r && pos.x >l && pos.y < t && pos.y > b){\n" +
29 | " float dis1 = abs(pos.x - l) / resolution.x;\n" +
30 | " float dis2 = abs(pos.x - r) / resolution.x;\n" +
31 | " float dis3 = abs(pos.y - t) / resolution.y;\n" +
32 | " float dis4 = abs(pos.y - b) / resolution.y;\n" +
33 | " //return 1.0;\n" +
34 | " float minDis = min(dis1,min(dis2,min(dis3,dis4)));\n" +
35 | " return smoothstep(0.0, coefficient.z, pow(minDis, coefficient.w));\n" +
36 | " } else{\n" +
37 | " return 0.0;\n" +
38 | " }\n" +
39 | " }\n" +
40 | "\n" +
41 | " void main()\n" +
42 | " {\n" +
43 | " vec2 centre = touchPoint;\n" +
44 | " vec4 tc = texture2D(inputImageTexture,textureCoordinate);\n" +
45 | " float mask = getMask(coefficient.y, gl_FragCoord.xy, centre);\n" +
46 | " if (coefficient.x == 0.0)\n" +
47 | " gl_FragColor = vec4(tc*mask*color);\n" +
48 | " else\n" +
49 | " gl_FragColor = vec4(tc*(1.0-coefficient.x*mask*color));\n" +
50 | " }";
51 |
52 | private int mRandomHandle;
53 |
54 | public OldMovieFilter() {
55 | super(VERTEX_SHADER, FRAGMENT_SHADER);
56 | }
57 |
58 | @Override
59 | public void initShader() {
60 | super.initShader();
61 | GLHelper.checkGlError();
62 | mRandomHandle = GLES20.glGetUniformLocation(mProgId, "uRandom");
63 | GLHelper.checkGlError();
64 | }
65 |
66 | @Override
67 | protected void preDraw(float progress) {
68 | super.preDraw(progress);
69 | float sinCount = 5f;
70 | float p = progress % (1/sinCount) / (1/sinCount);
71 | GLES20.glUniform1f(mRandomHandle, 1 + (float) Math.sin(p * Math.PI) * .2f);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/model/ErrorReason.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.model;
2 |
3 |
4 | /**
5 | * Created by yellowcat on 2015/6/2.
6 | */
7 | public class ErrorReason {
8 |
9 | private Throwable mThrowable;
10 | private String mExtra;
11 |
12 | public ErrorReason(Throwable cause,String extra) {
13 | mThrowable = cause;
14 | mExtra = extra;
15 | }
16 |
17 | public Throwable getThrowable() {
18 | return mThrowable;
19 | }
20 |
21 | public String getExtra() {
22 | return mExtra;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/model/PhotoData.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.model;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | /**
6 | * Created by huangwei on 2015/5/25.
7 | */
8 | public abstract class PhotoData {
9 |
10 | public static final int STATE_ERROR = -1;
11 | public static final int STATE_REMOTE = 0;
12 | public static final int STATE_DOWNLOADING = 1;
13 | public static final int STATE_LOCAL = 2;
14 | public static final int STATE_LOADING = 3;
15 | public static final int STATE_BITMAP = 4;
16 |
17 | protected String mUri;
18 | protected String mLocalUri;
19 | protected volatile Bitmap mBitmap;
20 |
21 | protected int mState;
22 | protected int mTargetState;
23 |
24 | private PhotoInfo mPhotoInfo;
25 |
26 | public PhotoData(String uri, int state) {
27 | this(uri, state, null);
28 | }
29 |
30 | public PhotoData(String uri, int state, PhotoInfo photoInfo) {
31 | mUri = uri;
32 | mState = state;
33 | mPhotoInfo = photoInfo;
34 | }
35 |
36 | /**
37 | * 可能返回null,只有状态为{@link #STATE_BITMAP}才返回bitmap
38 | *
39 | * @return
40 | */
41 | public Bitmap getBitmap() {
42 | return mBitmap;
43 | }
44 |
45 | /**
46 | * 可能返回null,只有状态为{@link #STATE_BITMAP}才返回bitmap
47 | *
48 | * @return
49 | */
50 | public Bitmap getBitmapAndRelease() {
51 | Bitmap bitmap = mBitmap;
52 | mBitmap = null;
53 | return bitmap;
54 | }
55 |
56 | public void setBitmap(Bitmap bitmap) {
57 | if (bitmap != null) {
58 | mBitmap = bitmap;
59 | }
60 | }
61 |
62 | public String getUri() {
63 | return mUri;
64 | }
65 |
66 | public int getState() {
67 | return mState;
68 | }
69 |
70 | public int getTargetState() {
71 | return mTargetState;
72 | }
73 |
74 | public PhotoInfo getPhotoInfo() {
75 | return mPhotoInfo;
76 | }
77 |
78 | public void setPhotoInfo(PhotoInfo photoInfo) {
79 | mPhotoInfo = photoInfo;
80 | }
81 |
82 | /**
83 | * @param targetState must be {@link #STATE_LOCAL} OR {@link #STATE_BITMAP}
84 | * @param onDataLoadListener
85 | */
86 | public abstract void prepareData(int targetState, OnDataLoadListener onDataLoadListener);
87 |
88 | public boolean isLocal() {
89 | return mState == STATE_LOCAL || mState == STATE_LOADING || mState == STATE_BITMAP;
90 | }
91 |
92 | public static class SimpleOnDataLoadListener implements OnDataLoadListener {
93 |
94 | @Override
95 | public void onDataLoaded(PhotoData photoData, Bitmap bitmap) {
96 |
97 | }
98 |
99 | @Override
100 | public void onDownloaded(PhotoData photoData) {
101 |
102 | }
103 |
104 | @Override
105 | public void onDownloadProgressUpdate(PhotoData photoData, int current, int total) {
106 |
107 | }
108 |
109 | @Override
110 | public void onError(PhotoData photoData, ErrorReason errorReason) {
111 |
112 | }
113 | }
114 |
115 | public interface OnDataLoadListener {
116 | void onDataLoaded(PhotoData photoData, Bitmap bitmap);
117 |
118 | void onDownloaded(PhotoData photoData);
119 |
120 | void onDownloadProgressUpdate(PhotoData photoData, int current, int total);
121 |
122 | void onError(PhotoData photoData, ErrorReason errorReason);
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/model/PhotoInfo.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.model;
2 |
3 | /**
4 | * Created by huangwei on 2015/6/10.
5 | */
6 | public class PhotoInfo {
7 | public Object extra;
8 | public String description;
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/moviefilter/CameoMovieFilter.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.moviefilter;
2 |
3 | import android.graphics.Rect;
4 | import android.graphics.RectF;
5 | import android.opengl.GLES20;
6 | import com.hw.photomovie.PhotoMovie;
7 | import com.hw.photomovie.opengl.FboTexture;
8 |
9 | /**
10 | * Created by huangwei on 2018/9/8.
11 | */
12 | public class CameoMovieFilter extends BaseMovieFilter {
13 |
14 | protected static final String FRAGMENT_SHADER =
15 | "precision mediump float;\n" +
16 | "varying vec2 textureCoordinate;\n" +
17 | "uniform sampler2D inputImageTexture;\n" +
18 | "const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);\n" +
19 | "uniform vec2 TexSize;\n" +
20 | "const vec4 bkColor = vec4(0.5, 0.5, 0.5, 1.0);\n" +
21 | "\n" +
22 | "void main()\n" +
23 | "{\n" +
24 | " vec2 tex = textureCoordinate;\n" +
25 | " vec2 upLeftUV = vec2(tex.x-1.0/TexSize.x, tex.y-1.0/TexSize.y);\n" +
26 | " vec4 curColor = texture2D(inputImageTexture, textureCoordinate);\n" +
27 | " vec4 upLeftColor = texture2D(inputImageTexture, upLeftUV);\n" +
28 | " vec4 delColor = curColor - upLeftColor;\n" +
29 | " float luminance = dot(delColor.rgb, W);\n" +
30 | " gl_FragColor = vec4(vec3(luminance), 0.0) + bkColor;\n" +
31 | "}";
32 |
33 | private int mTexSizeHandle;
34 | public CameoMovieFilter(){
35 | super(VERTEX_SHADER,FRAGMENT_SHADER);
36 | }
37 |
38 | @Override
39 | public void initShader() {
40 | super.initShader();
41 | mTexSizeHandle = GLES20.glGetUniformLocation(mProgId,"TexSize");
42 | }
43 |
44 | @Override
45 | protected void onPreDraw(PhotoMovie photoMovie, int elapsedTime, FboTexture inputTexture) {
46 | super.onPreDraw(photoMovie, elapsedTime,inputTexture);
47 | GLES20.glUniform2fv(mTexSizeHandle,1,new float[]{inputTexture.getTextureWidth(),inputTexture.getTextureHeight()},0);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/moviefilter/GrayMovieFilter.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.moviefilter;
2 |
3 | /**
4 | * Created by huangwei on 2018/9/8.
5 | */
6 | public class GrayMovieFilter extends BaseMovieFilter {
7 | protected static final String FRAGMENT_SHADER = "" +
8 | "varying highp vec2 textureCoordinate;\n" +
9 | " \n" +
10 | "uniform sampler2D inputImageTexture;\n" +
11 | " \n" +
12 | "void main()\n" +
13 | "{\n" +
14 | " mediump vec4 color = texture2D(inputImageTexture, textureCoordinate);\n" +
15 | " mediump float gray = color.r*0.3+color.g*0.59+color.b*0.11;\n"+
16 | " gl_FragColor = vec4(gray,gray,gray,1.0);\n"+
17 | "}";
18 | public GrayMovieFilter(){
19 | super(VERTEX_SHADER,FRAGMENT_SHADER);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/moviefilter/IMovieFilter.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.moviefilter;
2 |
3 | import com.hw.photomovie.PhotoMovie;
4 | import com.hw.photomovie.opengl.FboTexture;
5 |
6 | /**
7 | * Created by huangwei on 2018/9/5 0005.
8 | */
9 | public interface IMovieFilter {
10 | void doFilter(PhotoMovie photoMovie,int elapsedTime, FboTexture inputTexture, FboTexture outputTexture);
11 | void release();
12 | }
13 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/moviefilter/LutMovieFilter.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.moviefilter;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.opengl.GLES20;
6 | import android.util.Log;
7 | import com.hw.photomovie.PhotoMovie;
8 | import com.hw.photomovie.opengl.FboTexture;
9 | import com.hw.photomovie.util.AppResources;
10 |
11 | import static com.hw.photomovie.util.AppResources.loadShaderFromAssets;
12 |
13 | /**
14 | * Created by huangwei on 2018/9/8.
15 | */
16 | public class LutMovieFilter extends TwoTextureMovieFilter {
17 |
18 | public LutMovieFilter(Bitmap lutBitmap){
19 | super(loadShaderFromAssets("shader/two_vertex.glsl"),loadShaderFromAssets("shader/lut.glsl"));
20 | setBitmap(lutBitmap);
21 | }
22 |
23 | public LutMovieFilter(LutType type){
24 | super(loadShaderFromAssets("shader/two_vertex.glsl"),loadShaderFromAssets("shader/lut.glsl"));
25 | setBitmap(typeToBitmap(type));
26 | }
27 |
28 |
29 |
30 | public enum LutType{
31 | A,B,C,D,E
32 |
33 | }
34 | public static Bitmap typeToBitmap(LutType type){
35 | switch (type){
36 | case A:
37 | return AppResources.loadBitmapFromAssets("lut/lut_1.jpg");
38 | case B:
39 | return AppResources.loadBitmapFromAssets("lut/lut_2.jpg");
40 | case C:
41 | return AppResources.loadBitmapFromAssets("lut/lut_3.jpg");
42 | case D:
43 | return AppResources.loadBitmapFromAssets("lut/lut_4.jpg");
44 | case E:
45 | return AppResources.loadBitmapFromAssets("lut/lut_5.jpg");
46 | }
47 | return null;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/moviefilter/SnowMovieFilter.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.moviefilter;
2 |
3 | import android.graphics.Rect;
4 | import android.graphics.RectF;
5 | import android.opengl.GLES20;
6 | import android.util.Log;
7 | import com.hw.photomovie.PhotoMovie;
8 | import com.hw.photomovie.opengl.FboTexture;
9 |
10 | import static com.hw.photomovie.util.AppResources.loadShaderFromAssets;
11 |
12 | /**
13 | * Created by huangwei on 2018/9/8.
14 | */
15 | public class SnowMovieFilter extends BaseMovieFilter {
16 |
17 | private int mTimeHandler;
18 | private int mSizeHandler;
19 | private int mSnowSize = 3;
20 | private int mSpeed = 5;
21 | public SnowMovieFilter() {
22 | super(VERTEX_SHADER, loadShaderFromAssets("shader/snow.glsl"));
23 | }
24 |
25 | @Override
26 | public void initShader() {
27 | super.initShader();
28 | mTimeHandler = GLES20.glGetUniformLocation(getProgram(),"time");
29 | mSizeHandler = GLES20.glGetUniformLocation(getProgram(),"resolution");
30 | }
31 |
32 | @Override
33 | protected void onPreDraw(PhotoMovie photoMovie, int elapsedTime, FboTexture inputTexture) {
34 | super.onPreDraw(photoMovie, elapsedTime, inputTexture);
35 | float time = photoMovie==null?0f:elapsedTime/(float)photoMovie.getDuration();
36 | GLES20.glUniform1f(mTimeHandler,time*mSpeed);
37 | GLES20.glUniform2fv(mSizeHandler,1,new float[]{inputTexture.getWidth()/(float)inputTexture.getHeight()*mSnowSize,1f*mSnowSize},0);
38 |
39 | }
40 |
41 | public void setSnowSize(int mSnowSize) {
42 | this.mSnowSize = mSnowSize;
43 | }
44 |
45 | public void setSpeed(int mSpeed) {
46 | this.mSpeed = mSpeed;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/music/IMusicPlayer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.music;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetFileDescriptor;
5 | import android.media.MediaPlayer;
6 | import android.net.Uri;
7 |
8 | import java.io.FileDescriptor;
9 |
10 | /**
11 | * Created by huangwei on 2018/9/13 0013.
12 | */
13 | public interface IMusicPlayer {
14 | public void start();
15 | public void stop();
16 | public void pause();
17 | public void release();
18 |
19 | public void setDataSource(String path);
20 | public void setDataSource(FileDescriptor fileDescriptor);
21 | public void setDataSource(AssetFileDescriptor assetFileDescriptor);
22 | public void setDataSource(Context ctx, Uri uri);
23 |
24 | public void setErrorListener(MediaPlayer.OnErrorListener onErrorListener);
25 | public void setLooping(boolean loop);
26 | public boolean isPlaying();
27 | public void seekTo(int msec);
28 | }
29 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/BitmapTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import android.graphics.Bitmap;
4 | import android.opengl.GLES20;
5 | import junit.framework.Assert;
6 |
7 | import static com.hw.photomovie.util.GLUtil.NO_TEXTURE;
8 |
9 | // BitmapTexture is a texture whose content is specified by a fixed Bitmap.
10 | //
11 | // The texture does not own the Bitmap. The user should make sure the Bitmap
12 | // is valid during the texture's lifetime. When the texture is recycled, it
13 | // does not free the Bitmap.
14 | public class BitmapTexture extends UploadedTexture {
15 | protected Bitmap mContentBitmap;
16 | protected boolean mIsRecycled;
17 | /**
18 | * 默认情况是统一由GLESCanvas销毁,但是PhotoMovie循环播放时会导致纹理越来越多.
19 | * 因此这里改变默认行为
20 | */
21 | protected boolean mRecycleDirectly = true;
22 |
23 | public BitmapTexture(Bitmap bitmap) {
24 | this(bitmap, false);
25 | }
26 |
27 | public BitmapTexture(Bitmap bitmap, boolean hasBorder) {
28 | super(hasBorder);
29 | Assert.assertTrue(bitmap != null && !bitmap.isRecycled());
30 | mContentBitmap = bitmap;
31 | mIsRecycled = false;
32 | }
33 |
34 | @Override
35 | public void recycle() {
36 | mIsRecycled = true;
37 | if(mRecycleDirectly) {
38 | if (mId != NO_TEXTURE && GLES20.glIsTexture(mId)) {
39 | GLES20.glDeleteTextures(1, new int[]{mId}, 0);
40 | mId = NO_TEXTURE;
41 | }
42 | }
43 | super.recycle();
44 | }
45 |
46 | public void setRecycleDirectly(boolean recycleDirectly) {
47 | this.mRecycleDirectly = recycleDirectly;
48 | }
49 |
50 | @Override
51 | public void updateContent(GLESCanvas canvas) {
52 | // 当bitmap已经被释放,onGLIdle时还在上传队列中的该对象,崩溃
53 | if (mIsRecycled) {
54 | return;
55 | }
56 | super.updateContent(canvas);
57 | }
58 |
59 | @Override
60 | protected void onFreeBitmap(Bitmap bitmap) {
61 | // Do nothing.
62 | }
63 |
64 | @Override
65 | protected Bitmap onGetBitmap() {
66 | return mContentBitmap;
67 | }
68 |
69 | public Bitmap getBitmap() {
70 | return mContentBitmap;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/CanvasTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Bitmap.Config;
5 | import android.graphics.Canvas;
6 |
7 | // CanvasTexture is a texture whose content is the drawing on a Canvas.
8 | // The subclasses should override onDraw() to draw on the bitmap.
9 | // By default CanvasTexture is not opaque.
10 | abstract class CanvasTexture extends UploadedTexture {
11 | protected Canvas mCanvas;
12 | private final Config mConfig;
13 |
14 | public CanvasTexture(int width, int height) {
15 | mConfig = Config.ARGB_8888;
16 | setSize(width, height);
17 | setOpaque(false);
18 | }
19 |
20 | @Override
21 | protected Bitmap onGetBitmap() {
22 | Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, mConfig);
23 | mCanvas = new Canvas(bitmap);
24 | onDraw(mCanvas, bitmap);
25 | return bitmap;
26 | }
27 |
28 | @Override
29 | protected void onFreeBitmap(Bitmap bitmap) {
30 | if (!inFinalizer()) {
31 | bitmap.recycle();
32 | }
33 | }
34 |
35 | protected abstract void onDraw(Canvas canvas, Bitmap backing);
36 | }
37 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/ColorTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import com.hw.photomovie.util.Utils;
4 |
5 | // ColorTexture is a texture which fills the rectangle with the specified color.
6 | public class ColorTexture implements Texture {
7 |
8 | private final int mColor;
9 | private int mWidth;
10 | private int mHeight;
11 |
12 | public ColorTexture(int color) {
13 | mColor = color;
14 | mWidth = 1;
15 | mHeight = 1;
16 | }
17 |
18 | @Override
19 | public void draw(GLESCanvas canvas, int x, int y) {
20 | draw(canvas, x, y, mWidth, mHeight);
21 | }
22 |
23 | @Override
24 | public void draw(GLESCanvas canvas, int x, int y, int w, int h) {
25 | canvas.fillRect(x, y, w, h, mColor);
26 | }
27 |
28 | @Override
29 | public boolean isOpaque() {
30 | return Utils.isOpaque(mColor);
31 | }
32 |
33 | public void setSize(int width, int height) {
34 | mWidth = width;
35 | mHeight = height;
36 | }
37 |
38 | @Override
39 | public int getWidth() {
40 | return mWidth;
41 | }
42 |
43 | @Override
44 | public int getHeight() {
45 | return mHeight;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/ExtTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | // ExtTexture is a texture whose content comes from a external texture.
4 | // Before drawing, setSize() should be called.
5 | public class ExtTexture extends BasicTexture {
6 |
7 | private int mTarget;
8 |
9 | public ExtTexture(GLESCanvas canvas, int target) {
10 | GLId glId = canvas.getGLId();
11 | mId = glId.generateTexture();
12 | mTarget = target;
13 | }
14 |
15 | private void uploadToCanvas(GLESCanvas canvas) {
16 | canvas.setTextureParameters(this);
17 | setAssociatedCanvas(canvas);
18 | mState = STATE_LOADED;
19 | }
20 |
21 | @Override
22 | protected boolean onBind(GLESCanvas canvas) {
23 | if (!isLoaded()) {
24 | uploadToCanvas(canvas);
25 | }
26 |
27 | return true;
28 | }
29 |
30 | @Override
31 | public int getTarget() {
32 | return mTarget;
33 | }
34 |
35 | @Override
36 | public boolean isOpaque() {
37 | return true;
38 | }
39 |
40 | @Override
41 | public void yield() {
42 | // we cannot free the texture because we have no backup.
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/FadeInTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | // FadeInTexture is a texture which begins with a color, then gradually animates
4 | // into a given texture.
5 | public class FadeInTexture extends FadeTexture implements Texture {
6 | private final int mColor;
7 |
8 | public FadeInTexture(int color, BasicTexture texture) {
9 | super(texture);
10 | mColor = color;
11 | }
12 |
13 | @Override
14 | public void draw(GLESCanvas canvas, int x, int y, int w, int h) {
15 | if (isAnimating()) {
16 | canvas.drawMixed(mTexture, mColor, getRatio(), x, y, w, h);
17 | } else {
18 | mTexture.draw(canvas, x, y, w, h);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/FadeOutTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | // FadeOutTexture is a texture which begins with a given texture, then gradually animates
4 | // into fading out totally.
5 | public class FadeOutTexture extends FadeTexture {
6 | public FadeOutTexture(BasicTexture texture) {
7 | super(texture);
8 | }
9 |
10 | @Override
11 | public void draw(GLESCanvas canvas, int x, int y, int w, int h) {
12 | if (isAnimating()) {
13 | canvas.save(GLESCanvas.SAVE_FLAG_ALPHA);
14 | canvas.setAlpha(getRatio());
15 | mTexture.draw(canvas, x, y, w, h);
16 | canvas.restore();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/FadeTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import com.hw.photomovie.opengl.animations.AnimationTime;
4 | import com.hw.photomovie.util.Utils;
5 |
6 | // FadeTexture is a texture which fades the given texture along the time.
7 | public abstract class FadeTexture implements Texture {
8 | // The duration of the fading animation in milliseconds
9 | public static final int DURATION = 180;
10 | protected final BasicTexture mTexture;
11 | private final long mStartTime;
12 | private final int mWidth;
13 | private final int mHeight;
14 | private final boolean mIsOpaque;
15 | private boolean mIsAnimating;
16 |
17 | public FadeTexture(BasicTexture texture) {
18 | mTexture = texture;
19 | mWidth = mTexture.getWidth();
20 | mHeight = mTexture.getHeight();
21 | mIsOpaque = mTexture.isOpaque();
22 | mStartTime = now();
23 | mIsAnimating = true;
24 | }
25 |
26 | @Override
27 | public void draw(GLESCanvas canvas, int x, int y) {
28 | draw(canvas, x, y, mWidth, mHeight);
29 | }
30 |
31 | @Override
32 | public boolean isOpaque() {
33 | return mIsOpaque;
34 | }
35 |
36 | @Override
37 | public int getWidth() {
38 | return mWidth;
39 | }
40 |
41 | @Override
42 | public int getHeight() {
43 | return mHeight;
44 | }
45 |
46 | public boolean isAnimating() {
47 | if (mIsAnimating) {
48 | if (now() - mStartTime >= DURATION) {
49 | mIsAnimating = false;
50 | }
51 | }
52 | return mIsAnimating;
53 | }
54 |
55 | protected float getRatio() {
56 | float r = (float) (now() - mStartTime) / DURATION;
57 | return Utils.clamp(1.0f - r, 0.0f, 1.0f);
58 | }
59 |
60 | private long now() {
61 | return AnimationTime.get();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/GLES11IdImpl.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import javax.microedition.khronos.opengles.GL11;
4 | import javax.microedition.khronos.opengles.GL11ExtensionPack;
5 |
6 | /**
7 | * Open GL ES 1.1 implementation for generating and destroying texture IDs and
8 | * buffer IDs
9 | */
10 | public class GLES11IdImpl implements GLId {
11 | private static int sNextId = 1;
12 | // Mutex for sNextId
13 | private static Object sLock = new Object();
14 |
15 | @Override
16 | public int generateTexture() {
17 | synchronized (sLock) {
18 | return sNextId++;
19 | }
20 | }
21 |
22 | @Override
23 | public void glGenBuffers(int n, int[] buffers, int offset) {
24 | synchronized (sLock) {
25 | while (n-- > 0) {
26 | buffers[offset + n] = sNextId++;
27 | }
28 | }
29 | }
30 |
31 | @Override
32 | public void glDeleteTextures(GL11 gl, int n, int[] textures, int offset) {
33 | synchronized (sLock) {
34 | gl.glDeleteTextures(n, textures, offset);
35 | }
36 | }
37 |
38 | @Override
39 | public void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset) {
40 | synchronized (sLock) {
41 | gl.glDeleteBuffers(n, buffers, offset);
42 | }
43 | }
44 |
45 | @Override
46 | public void glDeleteFramebuffers(GL11ExtensionPack gl11ep, int n, int[] buffers, int offset) {
47 | synchronized (sLock) {
48 | gl11ep.glDeleteFramebuffersOES(n, buffers, offset);
49 | }
50 | }
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/GLES20IdImpl.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import android.opengl.GLES20;
4 |
5 | import javax.microedition.khronos.opengles.GL11;
6 | import javax.microedition.khronos.opengles.GL11ExtensionPack;
7 |
8 | public class GLES20IdImpl implements GLId {
9 | private final int[] mTempIntArray = new int[1];
10 |
11 | @Override
12 | public int generateTexture() {
13 | GLES20.glGenTextures(1, mTempIntArray, 0);
14 | GLES20Canvas.checkError();
15 | return mTempIntArray[0];
16 | }
17 |
18 | @Override
19 | public void glGenBuffers(int n, int[] buffers, int offset) {
20 | GLES20.glGenBuffers(n, buffers, offset);
21 | GLES20Canvas.checkError();
22 | }
23 |
24 | @Override
25 | public void glDeleteTextures(GL11 gl, int n, int[] textures, int offset) {
26 | GLES20.glDeleteTextures(n, textures, offset);
27 | GLES20Canvas.checkError();
28 | }
29 |
30 |
31 | @Override
32 | public void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset) {
33 | GLES20.glDeleteBuffers(n, buffers, offset);
34 | GLES20Canvas.checkError();
35 | }
36 |
37 | @Override
38 | public void glDeleteFramebuffers(GL11ExtensionPack gl11ep, int n, int[] buffers, int offset) {
39 | GLES20.glDeleteFramebuffers(n, buffers, offset);
40 | GLES20Canvas.checkError();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/GLId.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import javax.microedition.khronos.opengles.GL11;
4 | import javax.microedition.khronos.opengles.GL11ExtensionPack;
5 |
6 | /**
7 | * @Author Jituo.Xuan
8 | * @Date 11:40:51 AM Mar 20, 2014
9 | * @Comments:This mimics corresponding GL functions.
10 | */
11 | public interface GLId {
12 | public int generateTexture();
13 |
14 | public void glGenBuffers(int n, int[] buffers, int offset);
15 |
16 | public void glDeleteTextures(GL11 gl, int n, int[] textures, int offset);
17 |
18 | public void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset);
19 |
20 | public void glDeleteFramebuffers(GL11ExtensionPack gl11ep, int n, int[] buffers, int offset);
21 | }
22 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/GLPaint.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | public class GLPaint {
4 | private float mLineWidth = 1f;
5 | private int mColor = 0;
6 |
7 | public void setColor(int color) {
8 | mColor = color;
9 | }
10 |
11 | public int getColor() {
12 | return mColor;
13 | }
14 |
15 | public void setLineWidth(float width) {
16 | mLineWidth = width;
17 | }
18 |
19 | public float getLineWidth() {
20 | return mLineWidth;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/MGLES20Canvas.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | /**
4 | * Created by huangwei on 2015/5/29.
5 | */
6 | public class MGLES20Canvas extends GLES20Canvas{
7 |
8 | private int mSavedHashcode;
9 | private ShaderParameter[] parameters;
10 | @Override
11 | protected ShaderParameter[] prepareTexture(BasicTexture texture) {
12 | if(texture.hashCode() == mSavedHashcode){
13 | return parameters;
14 | }
15 | parameters = super.prepareTexture(texture);
16 | mSavedHashcode = texture.hashCode();
17 | return parameters;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/MultiLineTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.text.Layout;
6 | import android.text.StaticLayout;
7 | import android.text.TextPaint;
8 |
9 |
10 | // MultiLineTexture is a texture shows the content of a specified String.
11 | //
12 | // To create a MultiLineTexture, use the newInstance() method and specify
13 | // the String, the font size, and the color.
14 | class MultiLineTexture extends CanvasTexture {
15 | private final Layout mLayout;
16 |
17 | private MultiLineTexture(Layout layout) {
18 | super(layout.getWidth(), layout.getHeight());
19 | mLayout = layout;
20 | }
21 |
22 | public static MultiLineTexture newInstance(
23 | String text, int maxWidth, float textSize, int color,
24 | Layout.Alignment alignment) {
25 | TextPaint paint = StringTexture.getDefaultPaint(textSize, color, true);
26 | Layout layout = new StaticLayout(text, 0, text.length(), paint,
27 | maxWidth, alignment, 1, 0, true, null, 0);
28 |
29 | return new MultiLineTexture(layout);
30 | }
31 |
32 | @Override
33 | protected void onDraw(Canvas canvas, Bitmap backing) {
34 | mLayout.draw(canvas);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/NinePatchChunk.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import android.graphics.Rect;
4 |
5 | import java.nio.ByteBuffer;
6 | import java.nio.ByteOrder;
7 |
8 | // See "frameworks/base/include/utils/ResourceTypes.h" for the format of
9 | // NinePatch chunk.
10 | class NinePatchChunk {
11 |
12 | public static final int NO_COLOR = 0x00000001;
13 | public static final int TRANSPARENT_COLOR = 0x00000000;
14 |
15 | public Rect mPaddings = new Rect();
16 |
17 | public int mDivX[];
18 | public int mDivY[];
19 | public int mColor[];
20 |
21 | private static void readIntArray(int[] data, ByteBuffer buffer) {
22 | for (int i = 0, n = data.length; i < n; ++i) {
23 | data[i] = buffer.getInt();
24 | }
25 | }
26 |
27 | private static void checkDivCount(int length) {
28 | if (length == 0 || (length & 0x01) != 0) {
29 | throw new RuntimeException("invalid nine-patch: " + length);
30 | }
31 | }
32 |
33 | public static NinePatchChunk deserialize(byte[] data) {
34 | ByteBuffer byteBuffer =
35 | ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
36 |
37 | byte wasSerialized = byteBuffer.get();
38 | if (wasSerialized == 0) {
39 | return null;
40 | }
41 |
42 | NinePatchChunk chunk = new NinePatchChunk();
43 | chunk.mDivX = new int[byteBuffer.get()];
44 | chunk.mDivY = new int[byteBuffer.get()];
45 | chunk.mColor = new int[byteBuffer.get()];
46 |
47 | checkDivCount(chunk.mDivX.length);
48 | checkDivCount(chunk.mDivY.length);
49 |
50 | // skip 8 bytes
51 | byteBuffer.getInt();
52 | byteBuffer.getInt();
53 |
54 | chunk.mPaddings.left = byteBuffer.getInt();
55 | chunk.mPaddings.right = byteBuffer.getInt();
56 | chunk.mPaddings.top = byteBuffer.getInt();
57 | chunk.mPaddings.bottom = byteBuffer.getInt();
58 |
59 | // skip 4 bytes
60 | byteBuffer.getInt();
61 |
62 | readIntArray(chunk.mDivX, byteBuffer);
63 | readIntArray(chunk.mDivY, byteBuffer);
64 | readIntArray(chunk.mColor, byteBuffer);
65 |
66 | return chunk;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/RawTexture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import com.hw.photomovie.util.MLog;
4 |
5 | import javax.microedition.khronos.opengles.GL11;
6 |
7 | public class RawTexture extends BasicTexture {
8 | private static final String TAG = "RawTexture";
9 |
10 | private final boolean mOpaque;
11 | private boolean mIsFlipped;
12 |
13 | public RawTexture(int width, int height, boolean opaque) {
14 | mOpaque = opaque;
15 | setSize(width, height);
16 | }
17 |
18 | @Override
19 | public boolean isOpaque() {
20 | return mOpaque;
21 | }
22 |
23 | @Override
24 | public boolean isFlippedVertically() {
25 | return mIsFlipped;
26 | }
27 |
28 | public void setIsFlippedVertically(boolean isFlipped) {
29 | mIsFlipped = isFlipped;
30 | }
31 |
32 | public void prepare(GLESCanvas canvas) {
33 | GLId glId = canvas.getGLId();
34 | mId = glId.generateTexture();
35 | canvas.initializeTextureSize(this, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE);
36 | canvas.setTextureParameters(this);
37 | mState = STATE_LOADED;
38 | setAssociatedCanvas(canvas);
39 | }
40 |
41 | @Override
42 | protected boolean onBind(GLESCanvas canvas) {
43 | if (isLoaded()) {
44 | return true;
45 | }
46 | MLog.w(TAG, "lost the content due to context change");
47 | return false;
48 | }
49 |
50 | @Override
51 | public void yield() {
52 | // we cannot free the texture because we have no backup.
53 | }
54 |
55 | @Override
56 | protected int getTarget() {
57 | return GL11.GL_TEXTURE_2D;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/ScreenNail.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | import android.graphics.RectF;
4 |
5 | public interface ScreenNail {
6 | public int getWidth();
7 |
8 | public int getHeight();
9 |
10 | public boolean isReady();
11 |
12 | public void setLoadingTexture(StringTexture loadingTexture);
13 |
14 | public void draw(GLESCanvas canvas, int x, int y, int width, int height);
15 |
16 | // We do not need to draw this ScreenNail in this frame.
17 | public void noDraw();
18 |
19 | // This ScreenNail will not be used anymore. Release related resources.
20 | public void recycle();
21 |
22 | // This is only used by TileImageView to back up the tiles not yet loaded.
23 | public void draw(GLESCanvas canvas, RectF source, RectF dest);
24 | }
25 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/Texture.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl;
2 |
3 | /**
4 | * @Author Jituo.Xuan
5 | * @Date 11:38:11 AM Mar 20, 2014
6 | * @Comments:Texture is a rectangular image which can be drawn on GLCanvas.
7 | */
8 | public interface Texture {
9 | public int getWidth();
10 |
11 | public int getHeight();
12 |
13 | public void draw(GLESCanvas canvas, int x, int y);
14 |
15 | public void draw(GLESCanvas canvas, int x, int y, int w, int h);
16 |
17 | public boolean isOpaque();
18 | }
19 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/animations/AlphaAnim.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl.animations;
2 |
3 |
4 | import com.hw.photomovie.opengl.GLESCanvas;
5 | import com.hw.photomovie.util.Utils;
6 |
7 | public class AlphaAnim extends CanvasAnim {
8 | private final float mStartAlpha;
9 | private final float mEndAlpha;
10 | private float mCurrentAlpha;
11 |
12 | public AlphaAnim(float from, float to) {
13 | mStartAlpha = from;
14 | mEndAlpha = to;
15 | mCurrentAlpha = from;
16 | }
17 |
18 | @Override
19 | public void apply(GLESCanvas canvas) {
20 | canvas.multiplyAlpha(mCurrentAlpha);
21 | }
22 |
23 | @Override
24 | public int getCanvasSaveFlags() {
25 | return GLESCanvas.SAVE_FLAG_ALPHA;
26 | }
27 |
28 | @Override
29 | protected void onCalculate(float progress) {
30 | mCurrentAlpha = Utils.clamp(mStartAlpha + (mEndAlpha - mStartAlpha) * progress, 0f, 1f);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/animations/Animation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl.animations;
2 |
3 | import android.view.animation.Interpolator;
4 | import com.hw.photomovie.util.Utils;
5 |
6 | // Animation calculates a value according to the current input time.
7 | //
8 | // 1. First we need to use setDuration(int) to set the duration of the
9 | // animation. The duration is in milliseconds.
10 | // 2. Then we should call start(). The actual start time is the first value
11 | // passed to calculate(long).
12 | // 3. Each time we want to get an animation value, we call
13 | // calculate(long currentTimeMillis) to ask the Animation to calculate it.
14 | // The parameter passed to calculate(long) should be nonnegative.
15 | // 4. Use get() to get that value.
16 | //
17 | // In step 3, onCalculate(float progress) is called so subclasses can calculate
18 | // the value according to progress (progress is a value in [0,1]).
19 | //
20 | // Before onCalculate(float) is called, There is an optional interpolator which
21 | // can change the progress value. The interpolator can be set by
22 | // setInterpolator(Interpolator). If the interpolator is used, the value passed
23 | // to onCalculate may be (for example, the overshoot effect).
24 | //
25 | // The isActive() method returns true after the animation start() is called and
26 | // before calculate is passed a value which reaches the duration of the
27 | // animation.
28 | //
29 | // The start() method can be called again to restart the Animation.
30 | //
31 | public abstract class Animation {
32 |
33 | private static final String TAG = "Animation";
34 |
35 | private static final long ANIMATION_START = -1;
36 | private static final long NO_ANIMATION = -2;
37 |
38 | private long mStartTime = NO_ANIMATION;
39 | private int mDuration;
40 | private Interpolator mInterpolator;
41 |
42 | public void setInterpolator(Interpolator interpolator) {
43 | mInterpolator = interpolator;
44 | }
45 |
46 | public void setDuration(int duration) {
47 | mDuration = duration;
48 | }
49 |
50 | public void start() {
51 | mStartTime = ANIMATION_START;
52 | }
53 |
54 | public void setStartTime(long time) {
55 | mStartTime = time;
56 | }
57 |
58 | public boolean isActive() {
59 | return mStartTime != NO_ANIMATION;
60 | }
61 |
62 | public void forceStop() {
63 | mStartTime = NO_ANIMATION;
64 | }
65 |
66 | public boolean calculate(long currentTimeMillis) {
67 | if (mStartTime == NO_ANIMATION) {
68 | return false;
69 | }
70 | if (mStartTime == ANIMATION_START) {
71 | mStartTime = currentTimeMillis;
72 | }
73 | int elapse = (int) (currentTimeMillis - mStartTime);
74 | float x = Utils.clamp((float) elapse / mDuration, 0f, 1f);
75 | Interpolator i = mInterpolator;
76 | onCalculate(i != null ? i.getInterpolation(x) : x);
77 | if (elapse >= mDuration) {
78 | mStartTime = NO_ANIMATION;
79 | }
80 | return mStartTime != NO_ANIMATION;
81 | }
82 |
83 | protected abstract void onCalculate(float progress);
84 | }
85 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/animations/AnimationTime.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl.animations;
2 |
3 | import android.os.SystemClock;
4 |
5 | //
6 | // The animation time should ideally be the vsync time the frame will be
7 | // displayed, but that is an unknown time in the future. So we use the system
8 | // time just after eglSwapBuffers (when GLSurfaceView.onDrawFrame is called)
9 | // as a approximation.
10 | //
11 | public class AnimationTime {
12 | private static final String TAG = "AnimationTime";
13 |
14 | private static volatile long sTime;
15 |
16 | // Sets current time as the animation time.
17 | public static void update() {
18 |
19 | sTime = SystemClock.uptimeMillis();
20 | }
21 |
22 | // Returns the animation time.
23 | public static long get() {
24 | return sTime;
25 | }
26 |
27 | public static long startTime() {
28 | sTime = SystemClock.uptimeMillis();
29 | return sTime;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/animations/CanvasAnim.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl.animations;
2 |
3 |
4 | import com.hw.photomovie.opengl.GLESCanvas;
5 |
6 | public abstract class CanvasAnim extends Animation {
7 |
8 | public abstract int getCanvasSaveFlags();
9 |
10 | public abstract void apply(GLESCanvas canvas);
11 | }
12 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/animations/CaptureAnim.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hw.photomovie.opengl.animations;
18 |
19 | import android.view.animation.AccelerateDecelerateInterpolator;
20 | import android.view.animation.AccelerateInterpolator;
21 | import android.view.animation.DecelerateInterpolator;
22 | import android.view.animation.Interpolator;
23 |
24 | @SuppressWarnings("checkstyle:constantname")
25 |
26 | public class CaptureAnim {
27 | // The amount of change for zooming out.
28 | private static final float ZOOM_DELTA = 0.2f;
29 | // Pre-calculated value for convenience.
30 | private static final float ZOOM_IN_BEGIN = 1f - ZOOM_DELTA;
31 |
32 | private static final Interpolator sZoomOutInterpolator =
33 | new DecelerateInterpolator();
34 | private static final Interpolator sZoomInInterpolator =
35 | new AccelerateInterpolator();
36 | private static final Interpolator sSlideInterpolator =
37 | new AccelerateDecelerateInterpolator();
38 |
39 | // Calculate the slide factor based on the give time fraction.
40 | public static float calculateSlide(float fraction) {
41 | return sSlideInterpolator.getInterpolation(fraction);
42 | }
43 |
44 | // Calculate the scale factor based on the given time fraction.
45 | public static float calculateScale(float fraction) {
46 | float value;
47 | if (fraction <= 0.5f) {
48 | // Zoom in for the beginning.
49 | value = 1f - ZOOM_DELTA *
50 | sZoomOutInterpolator.getInterpolation(fraction * 2);
51 | } else {
52 | // Zoom out for the ending.
53 | value = ZOOM_IN_BEGIN + ZOOM_DELTA *
54 | sZoomInInterpolator.getInterpolation((fraction - 0.5f) * 2f);
55 | }
56 | return value;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/animations/FloatAnim.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl.animations;
2 |
3 | public class FloatAnim extends Animation {
4 |
5 | private final float mFrom;
6 | private final float mTo;
7 | private float mCurrent;
8 |
9 | public FloatAnim(float from, float to, int duration) {
10 | mFrom = from;
11 | mTo = to;
12 | mCurrent = from;
13 | setDuration(duration);
14 | }
15 |
16 | @Override
17 | protected void onCalculate(float progress) {
18 | mCurrent = mFrom + (mTo - mFrom) * progress;
19 | }
20 |
21 | public float get() {
22 | return mCurrent;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/opengl/animations/IntegerAnim.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.opengl.animations;
2 |
3 |
4 | import com.hw.photomovie.util.MLog;
5 |
6 | public class IntegerAnim extends Animation {
7 |
8 | private static final String TAG = "IntegerAnim";
9 |
10 | private int mTarget;
11 | private int mCurrent = 0;
12 | private int mFrom = 0;
13 | private boolean mEnabled = false;
14 |
15 | public void setEnabled(boolean enabled) {
16 | mEnabled = enabled;
17 | }
18 |
19 | public boolean isEnabled() {
20 | return mEnabled;
21 | }
22 |
23 | public void startAnimateTo(int target) {
24 |
25 | if (!mEnabled) {
26 | mTarget = mCurrent = target;
27 | return;
28 | }
29 | MLog.i(TAG, " target:" + target + " mTarget:" + mTarget);
30 | if (target == mTarget) {
31 | return;
32 | }
33 |
34 | mFrom = mCurrent;
35 | mTarget = target;
36 | setDuration(300);
37 | start();
38 | }
39 |
40 | public int get() {
41 | return mCurrent;
42 | }
43 |
44 | public int getTarget() {
45 | return mTarget;
46 | }
47 |
48 | @Override
49 | protected void onCalculate(float progress) {
50 | mCurrent = Math.round(mFrom + (1 - progress) * (mTarget - mFrom));
51 | if (progress == 0f) {
52 | mEnabled = false;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/record/gles/FullFrameRect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Google Inc. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hw.photomovie.record.gles;
18 |
19 | /**
20 | * This class essentially represents a viewport-sized sprite that will be rendered with
21 | * a texture, usually from an external source like the camera or video decoder.
22 | */
23 | public class FullFrameRect {
24 | private final Drawable2d mRectDrawable = new Drawable2d(Drawable2d.Prefab.FULL_RECTANGLE);
25 | private Texture2dProgram mProgram;
26 |
27 | /**
28 | * Prepares the object.
29 | *
30 | * @param program The program to use. FullFrameRect takes ownership, and will release
31 | * the program when no longer needed.
32 | */
33 | public FullFrameRect(Texture2dProgram program) {
34 | mProgram = program;
35 | }
36 |
37 | /**
38 | * Releases resources.
39 | *
40 | * This must be called with the appropriate EGL context current (i.e. the one that was
41 | * current when the constructor was called). If we're about to destroy the EGL context,
42 | * there's no value in having the caller make it current just to do this cleanup, so you
43 | * can pass a flag that will tell this function to skip any EGL-context-specific cleanup.
44 | */
45 | public void release(boolean doEglCleanup) {
46 | if (mProgram != null) {
47 | if (doEglCleanup) {
48 | mProgram.release();
49 | }
50 | mProgram = null;
51 | }
52 | }
53 |
54 | /**
55 | * Returns the program currently in use.
56 | */
57 | public Texture2dProgram getProgram() {
58 | return mProgram;
59 | }
60 |
61 | /**
62 | * Changes the program. The previous program will be released.
63 | *
64 | * The appropriate EGL context must be current.
65 | */
66 | public void changeProgram(Texture2dProgram program) {
67 | mProgram.release();
68 | mProgram = program;
69 | }
70 |
71 | /**
72 | * Creates a texture object suitable for use with drawFrame().
73 | */
74 | public int createTextureObject() {
75 | return mProgram.createTextureObject();
76 | }
77 |
78 | /**
79 | * Draws a viewport-filling rect, texturing it with the specified texture object.
80 | */
81 | public void drawFrame(int textureId, float[] texMatrix) {
82 | // Use the identity matrix for MVP so our 2x2 FULL_RECTANGLE covers the viewport.
83 | mProgram.draw(GlUtil.IDENTITY_MATRIX, mRectDrawable.getVertexArray(), 0,
84 | mRectDrawable.getVertexCount(), mRectDrawable.getCoordsPerVertex(),
85 | mRectDrawable.getVertexStride(),
86 | texMatrix, mRectDrawable.getTexCoordArray(), textureId,
87 | mRectDrawable.getTexCoordStride());
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/record/gles/OffscreenSurface.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Google Inc. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hw.photomovie.record.gles;
18 |
19 | /**
20 | * Off-screen EGL surface (pbuffer).
21 | *
22 | * It's good practice to explicitly release() the surface, preferably from a "finally" block.
23 | */
24 | public class OffscreenSurface extends EglSurfaceBase {
25 | /**
26 | * Creates an off-screen surface with the specified width and height.
27 | */
28 | public OffscreenSurface(EglCore eglCore, int width, int height) {
29 | super(eglCore);
30 | createOffscreenSurface(width, height);
31 | }
32 |
33 | /**
34 | * Releases any resources associated with the surface.
35 | */
36 | public void release() {
37 | releaseEglSurface();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/record/gles/WindowSurface.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Google Inc. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hw.photomovie.record.gles;
18 |
19 | import android.graphics.SurfaceTexture;
20 | import android.view.Surface;
21 |
22 | /**
23 | * Recordable EGL window surface.
24 | *
25 | * It's good practice to explicitly release() the surface, preferably from a "finally" block.
26 | */
27 | public class WindowSurface extends EglSurfaceBase {
28 | private Surface mSurface;
29 | private boolean mReleaseSurface;
30 |
31 | /**
32 | * Associates an EGL surface with the native window surface.
33 | *
34 | * Set releaseSurface to true if you want the Surface to be released when release() is
35 | * called. This is convenient, but can interfere with framework classes that expect to
36 | * manage the Surface themselves (e.g. if you release a SurfaceView's Surface, the
37 | * surfaceDestroyed() callback won't fire).
38 | */
39 | public WindowSurface(EglCore eglCore, Surface surface, boolean releaseSurface) {
40 | super(eglCore);
41 | createWindowSurface(surface);
42 | mSurface = surface;
43 | mReleaseSurface = releaseSurface;
44 | }
45 |
46 | /**
47 | * Associates an EGL surface with the SurfaceTexture.
48 | */
49 | public WindowSurface(EglCore eglCore, SurfaceTexture surfaceTexture) {
50 | super(eglCore);
51 | createWindowSurface(surfaceTexture);
52 | }
53 |
54 | /**
55 | * Releases any resources associated with the EGL surface (and, if configured to do so,
56 | * with the Surface as well).
57 | *
58 | * Does not require that the surface's EGL context be current.
59 | */
60 | public void release() {
61 | releaseEglSurface();
62 | if (mSurface != null) {
63 | if (mReleaseSurface) {
64 | mSurface.release();
65 | }
66 | mSurface = null;
67 | }
68 | }
69 |
70 | /**
71 | * Recreate the EGLSurface, using the new EglBase. The caller should have already
72 | * freed the old EGLSurface with releaseEglSurface().
73 | *
74 | * This is useful when we want to update the EGLSurface associated with a Surface.
75 | * For example, if we want to share with a different EGLContext, which can only
76 | * be done by tearing down and recreating the context. (That's handled by the caller;
77 | * this just creates a new EGLSurface for the Surface we were handed earlier.)
78 | *
79 | * If the previous EGLSurface isn't fully destroyed, e.g. it's still current on a
80 | * context somewhere, the create call will fail with complaints from the Surface
81 | * about already being connected.
82 | */
83 | public void recreate(EglCore newEglCore) {
84 | if (mSurface == null) {
85 | throw new RuntimeException("not yet implemented for SurfaceTexture");
86 | }
87 | mEglCore = newEglCore; // switch to new context
88 | createWindowSurface(mSurface); // create new surface
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/render/GLTextureMovieRender.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.render;
2 |
3 | import android.opengl.GLES20;
4 | import com.hw.photomovie.util.MLog;
5 |
6 | import javax.microedition.khronos.egl.EGLConfig;
7 | import javax.microedition.khronos.opengles.GL10;
8 |
9 | /**
10 | * Created by huangwei on 2018/9/6 0006.
11 | */
12 | public class GLTextureMovieRender extends GLSurfaceMovieRenderer {
13 |
14 | private static final String TAG = "GLTextureMovieRender";
15 | protected GLTextureView mGLTextureView;
16 |
17 | public GLTextureMovieRender(GLTextureView glTextureView) {
18 | mGLTextureView = glTextureView;
19 | mGLTextureView.setEGLContextClientVersion(2);
20 | mGLTextureView.setRenderer(new GLTextureView.Renderer() {
21 | @Override
22 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
23 | //资源起其实已经销毁了,这里只是告知其保存的纹理已经不可用,需要重建
24 | if (mMovieFilter != null) {
25 | mMovieFilter.release();
26 | }
27 | if(mCoverSegment!=null){
28 | mCoverSegment.release();
29 | }
30 | releaseTextures();
31 | mNeedRelease.set(false);
32 | mSurfaceCreated = true;
33 | prepare();
34 | }
35 |
36 | @Override
37 | public void onSurfaceChanged(GL10 gl, int width, int height) {
38 | setViewport(width, height);
39 | }
40 |
41 | @Override
42 | public boolean onDrawFrame(GL10 gl) {
43 | if (mNeedRelease.get()) {
44 | mNeedRelease.set(false);
45 | releaseGLResources();
46 | return false;
47 | }
48 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
49 | drawMovieFrame(mElapsedTime);
50 | return true;
51 | }
52 |
53 | @Override
54 | public void onSurfaceDestroyed() {
55 | mSurfaceCreated = false;
56 | mNeedRelease.set(false);
57 | }
58 | });
59 | mGLTextureView.setRenderMode(GLTextureView.RENDERMODE_WHEN_DIRTY);
60 | }
61 |
62 | @Override
63 | public void drawFrame(int elapsedTime) {
64 | mElapsedTime = elapsedTime;
65 | if (mRenderToRecorder) {
66 | onDrawFrame(null);
67 | return;
68 | }
69 | if (mSurfaceCreated) {
70 | mGLTextureView.requestRender();
71 | } else {
72 | MLog.e(TAG, "Surface not created!");
73 | }
74 | }
75 |
76 | @Override
77 | public void release() {
78 | mNeedRelease.set(true);
79 | if (mSurfaceCreated) {
80 | mGLTextureView.requestRender();
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/render/MovieRenderer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.render;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Rect;
5 | import android.graphics.RectF;
6 | import com.hw.photomovie.PhotoMovie;
7 | import com.hw.photomovie.opengl.GLESCanvas;
8 | import com.hw.photomovie.segment.MovieSegment;
9 | import com.hw.photomovie.segment.SingleBitmapSegment;
10 | import com.hw.photomovie.segment.WaterMarkSegment;
11 |
12 | import java.util.List;
13 |
14 | /**
15 | * Created by huangwei on 2015/5/26.
16 | */
17 | public abstract class MovieRenderer {
18 | protected PhotoMovie mPhotoMovie;
19 | protected volatile int mElapsedTime;
20 | protected Rect mViewportRect = new Rect();
21 | protected T mPainter;
22 | protected boolean mEnableDraw = true;
23 | protected OnReleaseListener mOnReleaseListener;
24 | protected MovieSegment mCurrentSegment;
25 | /**
26 | * 用于展示水印
27 | */
28 | protected MovieSegment mCoverSegment;
29 |
30 | public MovieRenderer() {
31 | }
32 |
33 | public abstract void drawFrame(int elapsedTime);
34 |
35 | public MovieRenderer setPainter(T painter) {
36 | mPainter = painter;
37 | return this;
38 | }
39 |
40 | public void drawMovieFrame(int elapsedTime) {
41 | if (mPhotoMovie == null || !mEnableDraw) {
42 | return;
43 | }
44 | PhotoMovie.SegmentPicker segmentPicker = mPhotoMovie.getSegmentPicker();
45 | MovieSegment movieSegment = segmentPicker.pickCurrentSegment(elapsedTime);
46 | if (movieSegment != null) {
47 | float segmentProgress = segmentPicker.getSegmentProgress(movieSegment, elapsedTime);
48 | if (movieSegment.showNextAsBackground()) {
49 | MovieSegment nextSegment = segmentPicker.getNextSegment(elapsedTime);
50 | if (nextSegment != null && nextSegment != movieSegment) {
51 | nextSegment.drawFrame(mPainter, 0);
52 | }
53 | }
54 | movieSegment.drawFrame(mPainter, segmentProgress);
55 | mCurrentSegment = movieSegment;
56 | }
57 | if(mCoverSegment!=null && mPainter instanceof GLESCanvas){
58 | mCoverSegment.drawFrame(mPainter,0);
59 | }
60 | }
61 |
62 | public void releaseCoverSegment() {
63 | if(mCoverSegment!=null){
64 | mCoverSegment.release();
65 | }
66 | }
67 |
68 | public void setMovieViewport(int l, int t, int r, int b) {
69 | if (mPhotoMovie != null) {
70 | for (MovieSegment segment : mPhotoMovie.getMovieSegments()) {
71 | segment.setViewport(l, t, r, b);
72 | }
73 | }
74 | if(mCoverSegment!=null){
75 | mCoverSegment.setViewport(l, t, r, b);
76 | }
77 | mViewportRect.set(l, t, r, b);
78 | }
79 |
80 | public void setPhotoMovie(PhotoMovie photoMovie) {
81 | mPhotoMovie = photoMovie;
82 | if (mViewportRect.width() > 0 && mViewportRect.height() > 0) {
83 | setMovieViewport(mViewportRect.left, mViewportRect.top, mViewportRect.right, mViewportRect.bottom);
84 | }
85 | }
86 |
87 | public PhotoMovie getPhotoMovie() {
88 | return mPhotoMovie;
89 | }
90 |
91 | public void enableDraw(boolean enableDraw) {
92 | mEnableDraw = enableDraw;
93 | }
94 |
95 | public abstract void release();
96 | public abstract void release(List> segments);
97 |
98 | public void setOnReleaseListener(OnReleaseListener listener) {
99 | mOnReleaseListener = listener;
100 | }
101 |
102 | public void setCoverSegment(MovieSegment coverSegment){
103 | mCoverSegment = coverSegment;
104 | }
105 |
106 | public interface OnReleaseListener {
107 | void onRelease();
108 | }
109 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/AbsLayerSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import com.hw.photomovie.opengl.GLESCanvas;
4 | import com.hw.photomovie.segment.layer.MovieLayer;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * Created by huangwei on 2015/6/3.
11 | */
12 | public abstract class AbsLayerSegment extends MulitBitmapSegment {
13 |
14 | protected MovieLayer[] mLayers;
15 |
16 | public AbsLayerSegment() {
17 | super();
18 | mLayers = initLayers();
19 | }
20 |
21 | public AbsLayerSegment(int duration) {
22 | super(duration);
23 | mLayers = initLayers();
24 | }
25 |
26 | protected abstract MovieLayer[] initLayers();
27 |
28 | @Override
29 | public void drawFrame(GLESCanvas canvas, float segmentProgress) {
30 | if (mLayers == null || mLayers.length == 0) {
31 | return;
32 | }
33 |
34 | for (int i = 0; i < mLayers.length; i++) {
35 | mLayers[i].drawFrame(canvas, segmentProgress);
36 | }
37 | }
38 |
39 | @Override
40 | public void setViewport(int l, int t, int r, int b) {
41 | super.setViewport(l, t, r, b);
42 | for (int i = 0; mLayers != null && i < mLayers.length; i++) {
43 | mLayers[i].setViewprot(l, t, r, b);
44 | }
45 | }
46 |
47 | @Override
48 | public int getRequiredPhotoNum() {
49 | int num = 0;
50 | for (int i = 0; mLayers != null && i < mLayers.length; i++) {
51 | num += mLayers[i].getRequiredPhotoNum();
52 | }
53 | return num;
54 | }
55 |
56 | @Override
57 | protected void onDataPrepared() {
58 | allocPhotoToLayers();
59 | for(int i=0;mLayers!=null && i photoDatas = new ArrayList();
70 | for (MovieLayer layer : mLayers) {
71 | photoDatas.clear();
72 | int required = layer.getRequiredPhotoNum();
73 | while (required > 0) {
74 | if (index >= mPhotos.size()) {
75 | index = 0;
76 | }
77 | photoDatas.add(mPhotoDataMap.get(mPhotos.get(index)));
78 | --required;
79 | ++index;
80 | }
81 | layer.allocPhotos(photoDatas);
82 | }
83 | }
84 |
85 | @Override
86 | public void onRelease() {
87 | super.onRelease();
88 | for(int i=0;mLayers!=null && i {
9 | }
10 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/GradientSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import com.hw.photomovie.opengl.GLESCanvas;
4 |
5 | /**
6 | * Created by huangwei on 2018/9/12 0012.
7 | */
8 | public class GradientSegment extends FitCenterSegment {
9 | /**
10 | * 缩放动画范围
11 | */
12 | private float mScaleFrom;
13 | private float mScaleTo;
14 | /**
15 | * 开始做alpha动画的进度
16 | */
17 | private float mAlphaStartProgress;
18 | private float mProgress;
19 |
20 | /**
21 | * @param duration 片段时长
22 | * @param alphaDuration 后半段的alpha动画时长
23 | * @param scaleFrom 缩放范围
24 | * @param scaleTo 缩放范围
25 | */
26 | public GradientSegment(int duration, int alphaDuration,float scaleFrom,float scaleTo) {
27 | super(duration);
28 | mScaleFrom = scaleFrom;
29 | mScaleTo = scaleTo;
30 | mAlphaStartProgress = (duration-alphaDuration) / (float) duration;
31 | }
32 |
33 | @Override
34 | protected void onDataPrepared() {
35 | super.onDataPrepared();
36 | }
37 |
38 | @Override
39 | public void drawFrame(GLESCanvas canvas, float segmentProgress) {
40 | mProgress = segmentProgress;
41 | super.drawFrame(canvas, segmentProgress);
42 | }
43 |
44 | @Override
45 | protected void drawContent(GLESCanvas canvas, float scale) {
46 | //FitCenterSegment已提供了缩放功能,这里我们只要提供自己需要的放大倍率即可
47 | scale = mScaleFrom + (mScaleTo - mScaleFrom) * mProgress;
48 |
49 | if (mProgress < mAlphaStartProgress) {
50 | //只展示放大动画
51 | super.drawContent(canvas, scale);
52 | } else {
53 | float alpha = 1 - (mProgress - mAlphaStartProgress) / (1 - mAlphaStartProgress);
54 | //加上alpha效果
55 | canvas.save();
56 | canvas.setAlpha(alpha);
57 | super.drawContent(canvas, scale);
58 | canvas.restore();
59 | }
60 | }
61 |
62 | @Override
63 | public boolean showNextAsBackground() {
64 | return true;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/GradientTransferSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import android.opengl.GLES20;
4 | import com.hw.photomovie.opengl.GLESCanvas;
5 |
6 | /**
7 | * Created by huangwei on 2018/9/12 0012.
8 | */
9 | public class GradientTransferSegment extends TransitionSegment {
10 | /**
11 | * 缩放动画范围
12 | */
13 | private float mPreScaleFrom;
14 | private float mPreScaleTo;
15 | private float mNextScaleFrom;
16 | private float mNextScaleTo;
17 |
18 | public GradientTransferSegment(int duration,
19 | float preScaleFrom, float preScaleTo,
20 | float nextScaleFrom, float nextScaleTo) {
21 | mPreScaleFrom = preScaleFrom;
22 | mPreScaleTo = preScaleTo;
23 | mNextScaleFrom = nextScaleFrom;
24 | mNextScaleTo = nextScaleTo;
25 | setDuration(duration);
26 | }
27 |
28 | @Override
29 | protected void onDataPrepared() {
30 |
31 | }
32 |
33 | @Override
34 | public void drawFrame(GLESCanvas canvas, float segmentProgress) {
35 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
36 | //下一个片段开始放大
37 | float nextScale = mNextScaleFrom + (mNextScaleTo - mNextScaleFrom) * segmentProgress;
38 | mNextSegment.drawContent(canvas, nextScale);
39 |
40 | //上一个片段继续放大同时变透明
41 | float preScale = mPreScaleFrom + (mPreScaleTo - mPreScaleFrom) * segmentProgress;
42 | float alpha = 1 - segmentProgress;
43 | mPreSegment.drawBackground(canvas);
44 | canvas.save();
45 | canvas.setAlpha(alpha);
46 | mPreSegment.drawContent(canvas, preScale);
47 | canvas.restore();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/LayerSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import com.hw.photomovie.segment.layer.MovieLayer;
4 |
5 | /**
6 | * Created by huangwei on 2015/6/10.
7 | */
8 | public class LayerSegment extends AbsLayerSegment {
9 |
10 | public LayerSegment(MovieLayer[] layers, int duration) {
11 | super(duration);
12 | mLayers = layers;
13 | }
14 |
15 | @Override
16 | protected MovieLayer[] initLayers() {
17 | return mLayers;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/MoveTransitionSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import android.animation.TimeInterpolator;
4 | import android.view.animation.DecelerateInterpolator;
5 | import com.hw.photomovie.opengl.GLESCanvas;
6 |
7 | /**
8 | * Created by huangwei on 2018/9/4 0004.
9 | */
10 | public class MoveTransitionSegment extends TransitionSegment {
11 |
12 | public static int DIRECTION_HORIZON = 0;
13 | public static int DIRECTION_VERTICAL = 1;
14 |
15 | private float mScaleFrom = 1f;
16 | private float mScaleTo = 0.7f;
17 | private int mDirection;
18 | private TimeInterpolator mInterpolator = new DecelerateInterpolator(1);
19 |
20 | public MoveTransitionSegment(int direction, int duration) {
21 | mDirection = direction;
22 | setDuration(duration);
23 | }
24 |
25 | @Override
26 | protected void onDataPrepared() {
27 | mNextSegment.onDataPrepared();
28 | }
29 |
30 | @Override
31 | public void drawFrame(GLESCanvas canvas, float segmentProgress) {
32 | segmentProgress = mInterpolator.getInterpolation(segmentProgress);
33 |
34 | canvas.fillRect(0, 0, mViewportRect.width(), mViewportRect.height(), mPreSegment.getBackgroundColor());
35 |
36 | canvas.save();
37 | canvas.setAlpha(1 - segmentProgress);
38 | float scale = mScaleFrom + (mScaleTo - mScaleFrom) * segmentProgress;
39 | mPreSegment.drawContent(canvas, scale);
40 | canvas.restore();
41 |
42 | if (mDirection == DIRECTION_VERTICAL) {
43 | canvas.save();
44 | canvas.translate(0, (1 - segmentProgress) * mViewportRect.height());
45 | mNextSegment.drawContent(canvas, 1f);
46 | canvas.restore();
47 | } else {
48 | canvas.save();
49 | canvas.translate((1 - segmentProgress) * mViewportRect.width(), 0);
50 | mNextSegment.drawContent(canvas, 1f);
51 | canvas.restore();
52 | }
53 | }
54 |
55 | @Override
56 | public void onPrepare() {
57 | super.onPrepare();
58 | }
59 |
60 | @Override
61 | public void setViewport(int l, int t, int r, int b) {
62 | super.setViewport(l, t, r, b);
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/ScaleSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import android.graphics.Bitmap;
4 | import com.hw.photomovie.model.PhotoData;
5 | import com.hw.photomovie.opengl.BitmapTexture;
6 | import com.hw.photomovie.opengl.GLESCanvas;
7 | import com.hw.photomovie.segment.animation.SrcAnimation;
8 | import com.hw.photomovie.segment.animation.SrcScaleAnimation;
9 | import com.hw.photomovie.util.Utils;
10 |
11 | /**
12 | * Created by huangwei on 2015/5/30.
13 | */
14 | public class ScaleSegment extends SingleBitmapSegment {
15 |
16 | private SrcAnimation mSrcAnimation;
17 | private float mFrom = 1f;
18 | private float mTo = 1f;
19 |
20 | public ScaleSegment(int duration, float from, float to) {
21 | this.mDuration = duration;
22 | mFrom = from;
23 | mTo = to;
24 | }
25 |
26 | public void onPrepare() {
27 | PhotoData photoData = this.getPhoto(0);
28 | if (photoData != null) {
29 | photoData.prepareData(4, new PluginListener(this));
30 | } else {
31 | throw new NullPointerException("PhotoData is null");
32 | }
33 | }
34 |
35 | protected void onDataPrepared() {
36 | mBitmapInfo.applyScaleType(mViewportRect);
37 | mSrcAnimation = new SrcScaleAnimation(mBitmapInfo.srcRect, mBitmapInfo.srcShowRect, mViewportRect, mFrom, mTo);
38 | mDataPrepared = true;
39 | }
40 |
41 | public void drawFrame(float segmentProgress) {
42 | }
43 |
44 | public void drawFrame(GLESCanvas canvas, float segmentRate) {
45 | if (!mDataPrepared) {
46 | return;
47 | }
48 | mSrcAnimation.update(segmentRate);
49 | if (this.mBitmapInfo != null && mBitmapInfo.bitmapTexture != null) {
50 | canvas.drawTexture(this.mBitmapInfo.bitmapTexture, this.mBitmapInfo.srcShowRect, this.mViewportRect);
51 | }
52 |
53 | }
54 |
55 | public int getRequiredPhotoNum() {
56 | return 1;
57 | }
58 |
59 | private class PluginListener extends PhotoData.SimpleOnDataLoadListener {
60 | private ScaleSegment segment;
61 |
62 | public PluginListener(ScaleSegment segment) {
63 | this.segment = segment;
64 | }
65 |
66 | @Override
67 | public void onDataLoaded(PhotoData photoData, Bitmap bitmap) {
68 | boolean success = false;
69 | if (Utils.isBitmapAvailable(bitmap)) {
70 | segment.mBitmapInfo = new BitmapInfo();
71 | segment.mBitmapInfo.bitmapTexture = new BitmapTexture(bitmap);
72 | segment.mBitmapInfo.srcRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
73 | segment.mBitmapInfo.srcShowRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
74 | segment.onDataPrepared();
75 | success = true;
76 | }
77 |
78 | if (segment.mOnSegmentPrepareListener != null) {
79 | segment.mOnSegmentPrepareListener.onSegmentPrepared(success);
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/ScaleTransSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import android.text.TextUtils;
4 | import com.hw.photomovie.model.PhotoData;
5 | import com.hw.photomovie.model.PhotoInfo;
6 | import com.hw.photomovie.opengl.GLESCanvas;
7 | import com.hw.photomovie.segment.layer.MovieLayer;
8 | import com.hw.photomovie.segment.layer.ScaleTransLayer;
9 | import com.hw.photomovie.segment.layer.SubtitleLayer;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * Created by huangwei on 2015/6/10.
15 | */
16 | public class ScaleTransSegment extends AbsLayerSegment{
17 |
18 | private static final int SCALE_DURATION_SHORT = 2000;
19 | private static final int SCALE_DURATION_LONG = 3000;
20 | private static final int TRANS_DURATION_LONG = 700;
21 |
22 | private int mScaleDuration;
23 |
24 | private String mDesStr;
25 |
26 | private ScaleTransLayer mScaleLayer;
27 | private SubtitleLayer mSubtitleLayer;
28 | private float mScaleRate;
29 |
30 | public ScaleTransSegment(){
31 | IS_DURATION_VARIABLE = true;
32 | }
33 | @Override
34 | protected MovieLayer[] initLayers() {
35 | mScaleLayer = new ScaleTransLayer(1f, 1.05f);
36 | mSubtitleLayer = new SubtitleLayer();
37 | return new MovieLayer[]{mScaleLayer, mSubtitleLayer};
38 | }
39 |
40 | @Override
41 | public void drawFrame(GLESCanvas canvas, float segmentProgress) {
42 | super.drawFrame(canvas, segmentProgress);
43 | }
44 |
45 | @Override
46 | public void onPrepare() {
47 | super.onPrepare();
48 | PhotoInfo photoInfo = null;
49 | if (mPhotos != null && mPhotos.size() > 0) {
50 | photoInfo = mPhotos.get(0).getPhotoInfo();
51 | }
52 | initSubtitle(photoInfo);
53 | }
54 |
55 | @Override
56 | public void allocPhotos(List photos) {
57 | super.allocPhotos(photos);
58 | // PhotoInfo photoInfo = null;
59 | // if (getAllocatedPhotos() != null && getAllocatedPhotos().size() > 0) {
60 | // photoInfo = getAllocatedPhotos().get(0).getPhotoInfo();
61 | // }
62 | // initSubtitle(photoInfo);
63 | }
64 |
65 | private void initSubtitle(PhotoInfo photoInfo) {
66 | mDesStr = photoInfo == null ? null : photoInfo.description;
67 | //字幕
68 | if (TextUtils.isEmpty(mDesStr)) {
69 | mScaleDuration = SCALE_DURATION_SHORT;
70 | } else {
71 | int count = mDesStr.length() / 15;
72 | count += mDesStr.length() % 15 == 0 ? 0 : 1;
73 | mScaleDuration = count * SCALE_DURATION_LONG;
74 | }
75 | mScaleRate = mScaleDuration / (float) (mScaleDuration + TRANS_DURATION_LONG);
76 | mScaleLayer.setScaleRate(mScaleRate);
77 | mSubtitleLayer.setDisappearRate(SCALE_DURATION_LONG / (float) (SCALE_DURATION_LONG + TRANS_DURATION_LONG));
78 | mSubtitleLayer.setSubtitle(mDesStr);
79 | }
80 |
81 | @Override
82 | public int getDuration() {
83 | return mScaleDuration + TRANS_DURATION_LONG;
84 | }
85 |
86 | @Override
87 | public int getRequiredPhotoNum() {
88 | return 1;
89 | }
90 |
91 | @Override
92 | public boolean showNextAsBackground() {
93 | return true;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/TestLayerSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import com.hw.photomovie.segment.layer.MovieLayer;
4 | import com.hw.photomovie.segment.layer.MovieTextLayer;
5 | import com.hw.photomovie.segment.layer.TestBaseLayer;
6 | import com.hw.photomovie.segment.layer.TestMuiltBitmapLayer;
7 |
8 | /**
9 | * Created by huangwei on 2015/6/4.
10 | */
11 | public class TestLayerSegment extends AbsLayerSegment {
12 |
13 | public TestLayerSegment() {
14 | super();
15 | }
16 |
17 | public TestLayerSegment(int duration) {
18 | super(duration);
19 | }
20 |
21 | @Override
22 | protected MovieLayer[] initLayers() {
23 | TestBaseLayer baseLayer = new TestBaseLayer();
24 | TestMuiltBitmapLayer testMuiltBitmapLayer = new TestMuiltBitmapLayer();
25 | testMuiltBitmapLayer.setParentLayer(baseLayer);
26 | MovieTextLayer movieTextLayer = new MovieTextLayer();
27 | return new MovieLayer[]{testMuiltBitmapLayer, baseLayer,movieTextLayer};
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/ThawSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import android.graphics.Color;
4 | import com.hw.photomovie.opengl.GLESCanvas;
5 | import com.hw.photomovie.segment.animation.SegmentAnimation;
6 | import com.hw.photomovie.segment.animation.SrcScaleAnimation;
7 | import com.hw.photomovie.segment.animation.SrcTransAnimation;
8 |
9 | /**
10 | * Created by huangwei on 2015/5/29.
11 | */
12 | public class ThawSegment extends SingleBitmapSegment {
13 |
14 | private SegmentAnimation mSrcAnimation;
15 | private int mType;
16 |
17 | public ThawSegment(int duration, int type) {
18 | mDuration = duration;
19 | mType = type;
20 | }
21 |
22 | @Override
23 | public void drawFrame(GLESCanvas canvas, float segmentRate) {
24 | if (!mDataPrepared) {
25 | return;
26 | }
27 | if (mBitmapInfo != null && mBitmapInfo.bitmapTexture != null && !mViewportRect.isEmpty()) {
28 | if(mSrcAnimation==null){
29 | createAnimation();
30 | }
31 | if (segmentRate < 0.2) {
32 | mSrcAnimation.update(0);
33 | float ratio = getValue(1, 0, 1 / 0.2f * segmentRate);
34 | if (mType == 0) {
35 | ratio = 0;
36 | }
37 | canvas.drawMixed(mBitmapInfo.bitmapTexture, Color.WHITE, ratio, mBitmapInfo.srcShowRect, mViewportRect);
38 | } else if (segmentRate > 0.8) {
39 | float ratio = getValue(0, 1, (segmentRate - 0.8f) * 5f);
40 | canvas.drawMixed(mBitmapInfo.bitmapTexture, Color.WHITE, ratio, mBitmapInfo.srcShowRect, mViewportRect);
41 | } else {
42 | float ratio = getValue(0, 1, (segmentRate - 0.2f) * 1 / 0.6f);
43 | mSrcAnimation.update(ratio);
44 | canvas.drawTexture(mBitmapInfo.bitmapTexture, mBitmapInfo.srcShowRect, mViewportRect);
45 | }
46 | }
47 | }
48 |
49 | @Override
50 | protected void onDataPrepared() {
51 | super.onDataPrepared();
52 | createAnimation();
53 | }
54 |
55 | @Override
56 | public int getRequiredPhotoNum() {
57 | return 1;
58 | }
59 |
60 | protected void createAnimation() {
61 | if (!mBitmapInfo.srcRect.isEmpty() && !mViewportRect.isEmpty()) {
62 | // mSrcAnimation = new SrcScaleAnimation(mSrcRect, mShowSrcRect, mViewportRect, 1f, 0.5f);
63 | switch (mType) {
64 | case 0:
65 | mSrcAnimation = new SrcScaleAnimation(mBitmapInfo.srcRect, mBitmapInfo.srcShowRect, mViewportRect, 1.0f, 1.1f);
66 | break;
67 | case 1:
68 | mSrcAnimation = new SrcTransAnimation(mBitmapInfo.srcRect, mBitmapInfo.srcShowRect, mViewportRect, -0.4f, 0);
69 | break;
70 | case 2:
71 | mSrcAnimation = new SrcTransAnimation(mBitmapInfo.srcRect, mBitmapInfo.srcShowRect, mViewportRect, 0.4f, 0f);
72 | break;
73 | }
74 | }
75 | }
76 |
77 | private float getValue(float from, float to, float progress) {
78 | return from + (to - from) * progress;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/TransitionSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * 转场片段,本身不需求照片,只持有上一个以及下一个片段,实现转场动画
7 | */
8 | public abstract class TransitionSegment extends MulitBitmapSegment {
9 |
10 | protected PRE mPreSegment;
11 | protected NEXT mNextSegment;
12 |
13 | @Override
14 | public void onPrepare() {
15 | List movieSegments = mPhotoMovie.getMovieSegments();
16 | int index = movieSegments.indexOf(this);
17 | if (index <= 0 || index == movieSegments.size() - 1) {
18 | throw new TransitionSegmentException("TransitionSegment must be in the middle of two other Segments");
19 | }
20 | mPreSegment = (PRE) movieSegments.get(index - 1);
21 | mNextSegment = (NEXT) movieSegments.get(index + 1);
22 | if (mPreSegment instanceof TransitionSegment || mNextSegment instanceof TransitionSegment) {
23 | throw new TransitionSegmentException("TransitionSegment must be in the middle of two other Segments");
24 | }
25 | mNextSegment.setOnSegmentPrepareListener(new OnSegmentPrepareListener() {
26 | @Override
27 | public void onSegmentPrepared(boolean success) {
28 | onDataPrepared();
29 | mNextSegment.setOnSegmentPrepareListener(null);
30 | }
31 | });
32 | mNextSegment.prepare();
33 | mPreSegment.enableRelease(false);
34 | }
35 |
36 | @Override
37 | public int getRequiredPhotoNum() {
38 | return 0;
39 | }
40 |
41 | private static class TransitionSegmentException extends RuntimeException {
42 | public TransitionSegmentException(String message) {
43 | super(message);
44 | }
45 | }
46 |
47 | @Override
48 | public void onRelease() {
49 | super.onRelease();
50 | if(mPreSegment!=null) {
51 | mPreSegment.enableRelease(true);
52 | mPreSegment.release();
53 | }
54 | }
55 |
56 | @Override
57 | protected boolean checkPrepared() {
58 | return false;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/WaterMarkSegment.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Rect;
5 | import android.graphics.RectF;
6 | import android.util.Log;
7 | import com.hw.photomovie.opengl.BitmapTexture;
8 | import com.hw.photomovie.opengl.GLESCanvas;
9 | import com.hw.photomovie.util.ScaleType;
10 |
11 | /**
12 | * Created by huangwei on 2018/10/26.
13 | */
14 | public class WaterMarkSegment extends SingleBitmapSegment implements Cloneable{
15 |
16 | private Bitmap mBitmap;
17 | private RectF mDstRect;
18 | private float mAlpha;
19 |
20 | public void setWaterMark(Bitmap bitmap, RectF dstRect,float alpha) {
21 | mBitmap = bitmap;
22 | mDstRect = new RectF(dstRect);
23 | mAlpha = alpha;
24 | synchronized (this) {
25 | mBitmapInfo = null;
26 | }
27 | }
28 |
29 | @Override
30 | public void onPrepare() {
31 | onDataPrepared();
32 | }
33 |
34 | @Override
35 | public void drawFrame(GLESCanvas canvas, float segmentRate) {
36 | synchronized (this) {
37 | if (mBitmapInfo == null && mBitmap != null && mDstRect != null) {
38 | BitmapTexture bitmapTexture = new BitmapTexture(mBitmap);
39 | bitmapTexture.setOpaque(false);
40 | mBitmapInfo = new BitmapInfo();
41 | mBitmapInfo.srcRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
42 | mBitmapInfo.srcShowRect.set(mBitmapInfo.srcRect);
43 | mBitmapInfo.scaleType = ScaleType.FIT_XY;
44 | mBitmapInfo.bitmapTexture = bitmapTexture;
45 | onDataPrepared();
46 | }
47 | }
48 | if (!mDataPrepared) {
49 | return;
50 | }
51 | if (mBitmapInfo != null && mBitmapInfo.makeTextureAvailable(canvas)) {
52 | canvas.save();
53 | canvas.setAlpha(mAlpha);
54 | canvas.drawTexture(mBitmapInfo.bitmapTexture, mBitmapInfo.srcShowRect, mDstRect);
55 | canvas.restore();
56 | }
57 | }
58 |
59 | @Override
60 | public WaterMarkSegment clone(){
61 | WaterMarkSegment waterMarkSegment = new WaterMarkSegment();
62 | waterMarkSegment.setWaterMark(mBitmap,mDstRect,mAlpha);
63 | return waterMarkSegment;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/DstAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.graphics.RectF;
4 |
5 | /**
6 | * 作用在输出Rect的动画,可用于缩放平移
7 | */
8 | public class DstAnimation extends SegmentAnimation {
9 |
10 | public RectF mDstRect ;
11 |
12 | public DstAnimation(RectF dstRect) {
13 | mDstRect = dstRect;
14 | }
15 |
16 | @Override
17 | public RectF update(float progress) {
18 | return mDstRect;
19 | }
20 |
21 | public void updateDstRect(RectF dstRect){
22 | mDstRect = dstRect;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/DstScaleAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.graphics.Matrix;
4 | import android.graphics.RectF;
5 |
6 | /**
7 | * Created by huangwei on 2015/6/10.
8 | */
9 | public class DstScaleAnimation extends DstAnimation {
10 |
11 | private float mFromScale;
12 | private float mToScale;
13 | private RectF mProgressDstRect = new RectF();
14 | private float mProgress;
15 | private Matrix mScaleMatrix = new Matrix();
16 |
17 | public DstScaleAnimation(RectF dstRect, float fromScale, float toScale) {
18 | super(dstRect);
19 | mFromScale = fromScale;
20 | mToScale = toScale;
21 | }
22 |
23 | @Override
24 | public RectF update(float progress) {
25 | mProgress = mInterpolator.getInterpolation(progress);
26 | mProgressDstRect.set(mDstRect);
27 | float scale = mFromScale + (mToScale - mFromScale) * mProgress;
28 | mScaleMatrix.setScale(scale, scale, mDstRect.centerX(), mDstRect.centerY());
29 | mScaleMatrix.mapRect(mProgressDstRect);
30 | return mProgressDstRect;
31 | }
32 |
33 | @Override
34 | public void updateDstRect(RectF dstRect) {
35 | super.updateDstRect(dstRect);
36 | update(mProgress);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/DstTransAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.graphics.RectF;
4 |
5 | /**
6 | * Created by huangwei on 2015/6/10.
7 | */
8 | public class DstTransAnimation extends DstAnimation {
9 |
10 | private float mTransX;
11 | private float mTransY;
12 | private RectF mProgressDstRect = new RectF();
13 | private float mProgress;
14 |
15 | public DstTransAnimation(RectF dstRect, float transX, float transY) {
16 | super(dstRect);
17 | mTransX = transX;
18 | mTransY = transY;
19 | }
20 |
21 | @Override
22 | public RectF update(float progress) {
23 | mProgress = mInterpolator.getInterpolation(progress);
24 | mProgressDstRect.set(mDstRect);
25 | mProgressDstRect.offset(mProgress * mDstRect.width() * mTransX, mProgress * mDstRect.height() * mTransY);
26 | return mProgressDstRect;
27 | }
28 |
29 | @Override
30 | public void updateDstRect(RectF dstRect) {
31 | super.updateDstRect(dstRect);
32 | update(mProgress);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/SegmentAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.animation.TimeInterpolator;
4 | import android.view.animation.LinearInterpolator;
5 |
6 | /**
7 | * Created by huangwei on 2015/5/29.
8 | */
9 | public abstract class SegmentAnimation {
10 | protected TimeInterpolator mInterpolator = new LinearInterpolator();
11 |
12 | public abstract Object update(float progress);
13 |
14 | public void setInterpolator(TimeInterpolator interpolator) {
15 | mInterpolator = interpolator;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/SrcAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.graphics.Rect;
4 | import android.graphics.RectF;
5 |
6 | /**
7 | * 作用在图片本身Rect的动画,可用于缩放平移
8 | */
9 | public abstract class SrcAnimation extends SegmentAnimation {
10 |
11 | protected Rect mSrcRect;
12 | protected RectF mSrcShowRect;
13 | protected RectF mDstRect;
14 | protected float mProgress;
15 |
16 | public SrcAnimation(Rect srcRect, RectF srcShowRect, RectF dstRect) {
17 | mSrcShowRect = srcShowRect;
18 | mSrcRect = srcRect;
19 | mDstRect = dstRect;
20 | }
21 |
22 | @Override
23 | public RectF update(float progress) {
24 | mProgress = progress;
25 | return mSrcShowRect;
26 | }
27 |
28 | public abstract void updateDstRect(RectF dstRect);
29 | }
30 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/SrcLeftRightAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.graphics.Rect;
4 | import android.graphics.RectF;
5 | import com.hw.photomovie.util.PhotoUtil;
6 |
7 | /**
8 | * Created by huangwei on 2015/6/10.
9 | * 从最左边扫到最右边
10 | */
11 | public class SrcLeftRightAnimation extends SrcAnimation {
12 | private RectF mMaxShowRect = new RectF();
13 | /**
14 | * 转移开始前的初始位置
15 | */
16 | private RectF mInitRect = new RectF();
17 |
18 | private float mTransDisX;
19 |
20 | /**
21 | * @param srcRect
22 | * @param srcShowRect
23 | * @param dstRect
24 | */
25 | public SrcLeftRightAnimation(Rect srcRect, RectF srcShowRect, RectF dstRect) {
26 | super(srcRect, srcShowRect, dstRect);
27 | updateDstRect(dstRect);
28 | }
29 |
30 | @Override
31 | public RectF update(float progress) {
32 | mProgress = mInterpolator.getInterpolation(progress);
33 | mSrcShowRect.set(mInitRect);
34 | mSrcShowRect.offset(mTransDisX * mProgress, 0);
35 | return mSrcShowRect;
36 | }
37 |
38 | @Override
39 | public void updateDstRect(RectF dstRect) {
40 | mDstRect = dstRect;
41 |
42 | mMaxShowRect.set(PhotoUtil.getCroppedRect(
43 | null,
44 | mSrcRect.width(),
45 | mSrcRect.height(),
46 | dstRect.width(),
47 | dstRect.height()));
48 |
49 | float cy = mSrcRect.centerY();
50 | float h = mMaxShowRect.height();
51 | mInitRect.set(0, cy - h / 2f, mMaxShowRect.width(), cy + h / 2f);
52 | mTransDisX = mSrcRect.width() - mMaxShowRect.width();
53 |
54 | update(mProgress);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/SrcScaleAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.graphics.Rect;
4 | import android.graphics.RectF;
5 | import com.hw.photomovie.util.PhotoUtil;
6 |
7 | /**
8 | * Created by huangwei on 2015/5/29.
9 | */
10 | public class SrcScaleAnimation extends SrcAnimation {
11 |
12 | private float mFrom;
13 | private float mTo;
14 |
15 | private RectF mMaxShowRect = new RectF();
16 |
17 | private float mFromW, mFromH, mToW, mToH;
18 | private float mX, mY;
19 |
20 | public SrcScaleAnimation(Rect srcRect, RectF srcShowRect, RectF dstRect, float from, float to) {
21 | super(srcRect, srcShowRect, dstRect);
22 | mFrom = from;
23 | mTo = to;
24 | updateDstRect(dstRect);
25 | }
26 |
27 | @Override
28 | public RectF update(float progress) {
29 | mProgress = mInterpolator.getInterpolation(progress);
30 | float w = mFromW + (mToW - mFromW) * mProgress;
31 | float h = mFromH + (mToH - mFromH) * mProgress;
32 | mSrcShowRect.set(mX - w / 2, mY - h / 2, mX + w / 2, mY + h / 2);
33 | return mSrcShowRect;
34 | }
35 |
36 | @Override
37 | public void updateDstRect(RectF dstRect) {
38 | mDstRect = dstRect;
39 | mMaxShowRect.set(PhotoUtil.getCroppedRect(null, mSrcRect.width(), mSrcRect.height(), dstRect.width(), dstRect.height()));
40 | mX = mSrcRect.centerX();
41 | mY = mSrcRect.centerY();
42 | if (mFrom >= mTo) {
43 | mToW = mMaxShowRect.width();
44 | mToH = mMaxShowRect.height();
45 | mFromH = mToH * (mTo / mFrom);
46 | mFromW = mToW * (mTo / mFrom);
47 | } else {
48 | mFromW = mMaxShowRect.width();
49 | mFromH = mMaxShowRect.height();
50 | mToH = mFromH * (mFrom / mTo);
51 | mToW = mFromW * (mFrom / mTo);
52 | }
53 |
54 | update(mProgress);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/animation/SrcTransAnimation.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.animation;
2 |
3 | import android.graphics.Rect;
4 | import android.graphics.RectF;
5 | import com.hw.photomovie.util.PhotoUtil;
6 |
7 | /**
8 | * Created by huangwei on 2015/5/29.
9 | */
10 | public class SrcTransAnimation extends SrcAnimation {
11 |
12 | private RectF mMaxShowRect = new RectF();
13 | /**
14 | * 转移开始前的初始位置
15 | */
16 | private RectF mInitRect = new RectF();
17 |
18 | private float mTransDisX, mTransDisY;
19 | private float mTransX, mTransY;
20 |
21 | public SrcTransAnimation(Rect srcRect, RectF srcShowRect, RectF dstRect, float transX, float transY) {
22 | super(srcRect, srcShowRect, dstRect);
23 | mTransX = transX;
24 | mTransY = transY;
25 | updateDstRect(dstRect);
26 | }
27 |
28 | @Override
29 | public RectF update(float progress) {
30 | mProgress = mInterpolator.getInterpolation(progress);
31 | mSrcShowRect.set(mInitRect);
32 | mSrcShowRect.offset(mTransDisX * mProgress, mTransDisY * mProgress);
33 | return mSrcShowRect;
34 | }
35 |
36 | @Override
37 | public void updateDstRect(RectF dstRect) {
38 | mDstRect = dstRect;
39 | mMaxShowRect.set(PhotoUtil.getCroppedRect(
40 | null,
41 | mSrcRect.width(),
42 | mSrcRect.height(),
43 | dstRect.width() * (1 + Math.abs(mTransX)),
44 | dstRect.height() * (1 + Math.abs(mTransY))));
45 | float w = mMaxShowRect.width() / (1 + Math.abs(mTransX));
46 | float h = mMaxShowRect.height() / (1 + Math.abs(mTransY));
47 | mSrcShowRect.set(0, 0, w, h);
48 |
49 | if (mTransX > 0) {
50 | mSrcShowRect.offsetTo(mMaxShowRect.left, mSrcShowRect.top);
51 | } else if (mTransX < 0) {
52 | mSrcShowRect.offsetTo(mMaxShowRect.right - mSrcShowRect.width(), mSrcShowRect.top);
53 | } else {
54 | mSrcShowRect.offsetTo(mMaxShowRect.centerX() - w / 2, mSrcShowRect.top);
55 | }
56 |
57 | if (mTransY > 0) {
58 | mSrcShowRect.offsetTo(mSrcShowRect.left, mMaxShowRect.top);
59 | } else if (mTransY < 0) {
60 | mSrcShowRect.offsetTo(mSrcShowRect.left, mMaxShowRect.bottom - mSrcShowRect.height());
61 | } else {
62 | mSrcShowRect.offsetTo(mSrcShowRect.left, mMaxShowRect.centerY() - h / 2);
63 | }
64 |
65 | mInitRect.set(mSrcShowRect);
66 | mTransDisX = mSrcShowRect.width() * mTransX;
67 | mTransDisY = mSrcShowRect.height() * mTransY;
68 |
69 | update(mProgress);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/layer/AvailableRect.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.layer;
2 |
3 | import android.graphics.PointF;
4 | import android.graphics.RectF;
5 |
6 | /**
7 | * Created by huangwei on 2015/6/3.
8 | */
9 | public class AvailableRect {
10 | public RectF rectF;
11 | public float rotation;
12 | /**
13 | * 为null则以区域中点为中心点
14 | */
15 | public PointF rotationPivot;
16 | }
17 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/layer/GaussianBlurLayer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.layer;
2 |
3 | import android.graphics.Bitmap;
4 | import com.hw.photomovie.opengl.BitmapTexture;
5 | import com.hw.photomovie.opengl.GLESCanvas;
6 | import com.hw.photomovie.segment.BitmapInfo;
7 | import com.hw.photomovie.util.AppResources;
8 | import com.hw.photomovie.util.stackblur.StackBlurManager;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by huangwei on 2015/6/10.
14 | */
15 | public class GaussianBlurLayer extends MovieLayer {
16 | public static final int BLUR_RADIUS_DEFAULT = 10;
17 | private BitmapInfo mBitmapInfo;
18 | private BitmapInfo mBluredBitmapInfo;
19 |
20 | private float mBlurRadius = 10;
21 |
22 | @Override
23 | public void drawFrame(GLESCanvas canvas, float progress) {
24 | if (mBitmapInfo != null && mBluredBitmapInfo != null) {
25 | canvas.drawTexture(mBitmapInfo.bitmapTexture, mBitmapInfo.srcShowRect, mViewprotRect);
26 | canvas.drawMixed(mBluredBitmapInfo.bitmapTexture, 0, 1 - progress, mBluredBitmapInfo.srcShowRect, mViewprotRect);
27 | }
28 | }
29 |
30 | @Override
31 | public int getRequiredPhotoNum() {
32 | return 1;
33 | }
34 |
35 | @Override
36 | public void prepare() {
37 |
38 | }
39 |
40 | @Override
41 | public void release() {
42 |
43 | }
44 |
45 | @Override
46 | public void allocPhotos(List bitmapInfos) {
47 | super.allocPhotos(bitmapInfos);
48 | if (bitmapInfos != null && bitmapInfos.size() > 0) {
49 | mBitmapInfo = bitmapInfos.get(0);
50 | }
51 |
52 | if (mBitmapInfo != null) {
53 | mBlurRadius = BLUR_RADIUS_DEFAULT * AppResources.getInstance().getAppDensity() + 0.5f;
54 | Bitmap bitmap = mBitmapInfo.bitmapTexture.getBitmap();
55 | StackBlurManager manager = new StackBlurManager(bitmap, 0.125f);
56 | Bitmap bluredBitmap = manager.process((int) (mBlurRadius * 0.125f));
57 | mBluredBitmapInfo = new BitmapInfo();
58 | mBluredBitmapInfo.bitmapTexture = new BitmapTexture(bluredBitmap);
59 | mBluredBitmapInfo.bitmapTexture.setOpaque(false);
60 | mBluredBitmapInfo.srcRect.set(0, 0, bluredBitmap.getWidth(), bluredBitmap.getHeight());
61 | mBluredBitmapInfo.applyScaleType(mViewprotRect);
62 | }
63 | }
64 |
65 | @Override
66 | public void setViewprot(int l, int t, int r, int b) {
67 | super.setViewprot(l, t, r, b);
68 | if (mBluredBitmapInfo != null) {
69 | mBluredBitmapInfo.applyScaleType(mViewprotRect);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/layer/MovieLayer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.layer;
2 |
3 | import android.graphics.RectF;
4 | import com.hw.photomovie.opengl.GLESCanvas;
5 | import com.hw.photomovie.segment.BitmapInfo;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | /**
11 | * Created by huangwei on 2015/6/3.
12 | */
13 | public abstract class MovieLayer {
14 |
15 | protected List mBitmapInfos = new ArrayList();
16 | protected RectF mViewprotRect = new RectF();
17 |
18 | protected MovieLayer mParentLayer;
19 | /**
20 | * 给child指定的显示区域
21 | */
22 | protected AvailableRect[] mBaseChildAvailableRect;
23 | /**
24 | * 指定下一层的可用区域,左上角0,0,右下角1,1
25 | * 该数组长度必须是5的整数倍
26 | * 每五个元素分别代表一个显示区域的x1,y1,x2,y2,rotation
27 | * 在{@link #setViewprot(int, int, int, int)}时会将次数组转化成实际的{@link #mBaseChildAvailableRect}数组
28 | */
29 | protected float[] NEXT_AVAILABLE_RECT;
30 | private String subtitle;
31 |
32 | public abstract void drawFrame(GLESCanvas canvas, float progress);
33 |
34 | /**
35 | * 获取该层指定的更上层的输出区域
36 | *
37 | * @return
38 | */
39 | public AvailableRect[] getChildLayerRects(float progress) {
40 | return mBaseChildAvailableRect;
41 | }
42 |
43 | /**
44 | * 指定该层的parent
45 | */
46 | public void setParentLayer(MovieLayer parentLayer) {
47 | mParentLayer = parentLayer;
48 | }
49 |
50 | public void setViewprot(int l, int t, int r, int b) {
51 | mViewprotRect.set(l, t, r, b);
52 | if (NEXT_AVAILABLE_RECT == null || NEXT_AVAILABLE_RECT.length == 0 || NEXT_AVAILABLE_RECT.length % 5 != 0) {
53 | //默认指定chilid的显示区域为整个窗口区域
54 | AvailableRect availableRect = new AvailableRect();
55 | availableRect.rectF = new RectF(mViewprotRect);
56 | availableRect.rotation = 0;
57 | mBaseChildAvailableRect = new AvailableRect[]{availableRect};
58 | return;
59 | }
60 | mBaseChildAvailableRect = new AvailableRect[NEXT_AVAILABLE_RECT.length / 5];
61 | for (int i = 0; i < NEXT_AVAILABLE_RECT.length; i += 5) {
62 | float x1 = NEXT_AVAILABLE_RECT[i];
63 | float y1 = NEXT_AVAILABLE_RECT[i + 1];
64 | float x2 = NEXT_AVAILABLE_RECT[i + 2];
65 | float y2 = NEXT_AVAILABLE_RECT[i + 3];
66 | float rotation = NEXT_AVAILABLE_RECT[i + 4];
67 |
68 | AvailableRect availableRect = new AvailableRect();
69 | availableRect.rectF = new RectF(
70 | l + mViewprotRect.width() * x1,
71 | t + mViewprotRect.height() * y1,
72 | l + mViewprotRect.width() * x2,
73 | t + mViewprotRect.height() * y2);
74 | availableRect.rotation = rotation;
75 | mBaseChildAvailableRect[i / 5] = availableRect;
76 | }
77 | }
78 |
79 | /**
80 | * 该layer需要多少张照片
81 | *
82 | * @return
83 | */
84 | public abstract int getRequiredPhotoNum();
85 |
86 | public void allocPhotos(List bitmapInfos) {
87 | mBitmapInfos.clear();
88 | mBitmapInfos.addAll(bitmapInfos);
89 | }
90 |
91 | public abstract void prepare();
92 |
93 | public abstract void release();
94 | }
95 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/layer/TestBaseLayer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.layer;
2 |
3 | import android.graphics.PointF;
4 | import android.graphics.RectF;
5 | import com.hw.photomovie.opengl.BitmapTexture;
6 | import com.hw.photomovie.opengl.GLESCanvas;
7 |
8 | /**
9 | * Created by huangwei on 2015/6/3.
10 | */
11 | public class TestBaseLayer extends MovieLayer {
12 |
13 | protected BitmapTexture mBitmapTexture;
14 | protected RectF mSrcRect = new RectF();
15 |
16 | public TestBaseLayer() {
17 | // NEXT_AVAILABLE_RECT = new float[]{
18 | // 0.25f, 0.25f, 0.35f, 0.35f, 0f,
19 | // 0.5f, 0.5f, 0.85f, 0.9f, 60f
20 | // };
21 | NEXT_AVAILABLE_RECT = new float[]{
22 | 40 / 800f, 110 / 589f, 410 / 800f, 388 / 598f, 0f,
23 | 607 / 800f, 43 / 589f, 741 / 800f, 141 / 598f, 0f,
24 | 623 / 800f, 229 / 589f, 731 / 800f, 376 / 598f, 0f,
25 | 607 / 800f, 468 / 589f, 741 / 800f, 564 / 598f, 0f
26 | };
27 | }
28 |
29 | @Override
30 | public void prepare() {
31 | // Bitmap bitmap = BitmapFactory.decodeResource(AppResources.getInstance().getAppRes(), R.drawable.testpng);
32 | // mSrcRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
33 | // mBitmapTexture = new BitmapTexture(bitmap);
34 | // mBitmapTexture.setOpaque(false);
35 | }
36 |
37 | @Override
38 | public void release() {
39 | if (mBitmapTexture != null) {
40 | mBitmapTexture.recycle();
41 | }
42 | }
43 |
44 | @Override
45 | public void drawFrame(GLESCanvas canvas, float progress) {
46 | if (mBitmapTexture != null) {
47 | canvas.save();
48 | canvas.translate(mViewprotRect.centerX(), mViewprotRect.centerY());
49 | canvas.rotate(-0, 0, 0, -1f);
50 | canvas.translate(-mViewprotRect.centerX(), -mViewprotRect.centerY());
51 | canvas.drawTexture(mBitmapTexture, mSrcRect, mViewprotRect);
52 | canvas.restore();
53 | }
54 | }
55 |
56 | @Override
57 | public AvailableRect[] getChildLayerRects(float progress) {
58 | AvailableRect[] availableRects = super.getChildLayerRects(progress);
59 | for (int i = 0; availableRects != null && i < availableRects.length; i++) {
60 | availableRects[i].rotation = 0;
61 | //720*2 * progress;
62 | if (availableRects[i].rotationPivot == null) {
63 | availableRects[i].rotationPivot = new PointF();
64 | }
65 | availableRects[i].rotationPivot.set(mViewprotRect.centerX(), mViewprotRect.centerY());
66 | }
67 | return availableRects;
68 | }
69 |
70 | @Override
71 | public int getRequiredPhotoNum() {
72 | return 0;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/layer/TestMuiltBitmapLayer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.layer;
2 |
3 | import android.graphics.Rect;
4 | import com.hw.photomovie.opengl.GLESCanvas;
5 | import com.hw.photomovie.segment.BitmapInfo;
6 | import com.hw.photomovie.util.PhotoUtil;
7 | import com.hw.photomovie.util.ScaleType;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * Created by huangwei on 2015/6/3.
13 | */
14 | public class TestMuiltBitmapLayer extends MovieLayer {
15 |
16 | private Rect mTempRect = new Rect();
17 |
18 | @Override
19 | public void drawFrame(GLESCanvas canvas, float progress) {
20 | AvailableRect[] dstAvailableRect = mParentLayer == null ? null : mParentLayer.getChildLayerRects(progress);
21 |
22 | if (mBitmapInfos == null || dstAvailableRect == null || dstAvailableRect.length == 0) {
23 | return;
24 | }
25 |
26 | for (int i = 0; i < dstAvailableRect.length; i++) {
27 | AvailableRect availableRect = dstAvailableRect[i];
28 | BitmapInfo bitmapInfo = i < mBitmapInfos.size() ? mBitmapInfos.get(i) : null;
29 | if (bitmapInfo == null || bitmapInfo.bitmapTexture == null || availableRect == null || availableRect.rectF == null) {
30 | continue;
31 | }
32 | //更新bitmap显示区域
33 | if (bitmapInfo.scaleType == ScaleType.CENTER_CROP) {
34 | PhotoUtil.getCroppedRect(
35 | mTempRect,
36 | bitmapInfo.srcRect.width(),
37 | bitmapInfo.srcRect.height(),
38 | dstAvailableRect[i].rectF.width(),
39 | dstAvailableRect[i].rectF.height());
40 | bitmapInfo.srcShowRect.set(mTempRect);
41 | }
42 |
43 | canvas.save();
44 | float cx, cy;
45 | if (availableRect.rotationPivot == null) {
46 | cx = availableRect.rectF.centerX();
47 | cy = availableRect.rectF.centerY();
48 | } else {
49 | cx = availableRect.rotationPivot.x;
50 | cy = availableRect.rotationPivot.y;
51 | }
52 | canvas.translate(cx, cy);
53 | canvas.rotate(-availableRect.rotation, 0f, 0f, -1f);
54 | canvas.translate(-cx, -cy);
55 | canvas.drawTexture(bitmapInfo.bitmapTexture, bitmapInfo.srcShowRect, availableRect.rectF);
56 | canvas.restore();
57 | }
58 | }
59 |
60 | @Override
61 | public void allocPhotos(List bitmapInfos) {
62 | super.allocPhotos(bitmapInfos);
63 | }
64 |
65 | @Override
66 | public AvailableRect[] getChildLayerRects(float progress) {
67 | return null;
68 | }
69 |
70 | @Override
71 | public int getRequiredPhotoNum() {
72 | return 4;
73 | }
74 |
75 | @Override
76 | public void prepare() {
77 |
78 | }
79 |
80 | @Override
81 | public void release() {
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/strategy/NotRetryStrategy.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.strategy;
2 |
3 | import com.hw.photomovie.PhotoMovie;
4 | import com.hw.photomovie.model.PhotoData;
5 | import com.hw.photomovie.segment.MovieSegment;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by Administrator on 2015/6/12.
11 | */
12 | public class NotRetryStrategy implements RetryStrategy {
13 | @Override
14 | public List getAvailableData(PhotoMovie photoMovie, MovieSegment movieSegment) {
15 | return movieSegment==null?null:movieSegment.getAllocatedPhotos();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/segment/strategy/ReallocStrategy.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.segment.strategy;
2 |
3 | import com.hw.photomovie.PhotoMovie;
4 | import com.hw.photomovie.model.PhotoData;
5 | import com.hw.photomovie.segment.MovieSegment;
6 |
7 | import java.util.ArrayList;
8 | import java.util.LinkedList;
9 | import java.util.List;
10 |
11 | /**
12 | * Created by Administrator on 2015/6/12.
13 | */
14 | public class ReallocStrategy implements RetryStrategy {
15 | @Override
16 | public List getAvailableData(PhotoMovie photoMovie, MovieSegment movieSegment) {
17 | if (movieSegment == null) {
18 | return null;
19 | }
20 | if (photoMovie == null || photoMovie.getPhotoSource() == null) {
21 | return movieSegment.getAllocatedPhotos();
22 | }
23 |
24 | int required = movieSegment.getRequiredPhotoNum();
25 | List segmentDatas = new LinkedList(movieSegment.getAllocatedPhotos());
26 | for (int i = segmentDatas.size() - 1; i >= 0; i--) {
27 | PhotoData photoData = segmentDatas.get(i);
28 | //未加载好
29 | if (photoData.getState() < PhotoData.STATE_LOCAL) {
30 | segmentDatas.remove(i);
31 | }
32 | }
33 | //还需要多少
34 | int need = required - segmentDatas.size();
35 | List source = photoMovie.getPhotoSource().getSourceData();
36 | List availableList = new ArrayList();
37 | for (PhotoData photoData : source) {
38 | //跳过没准备好或者已有的
39 | if (photoData.getState() < PhotoData.STATE_LOCAL || segmentDatas.contains(photoData)) {
40 | continue;
41 | }
42 | if (need <= 0) {
43 | return segmentDatas;
44 | }
45 | availableList.add(photoData);
46 | }
47 | //从可用的里面随机选
48 | while(need > 0 && availableList.size()>0){
49 | int ran = (int) (Math.random() * availableList.size());
50 | segmentDatas.add(availableList.get(ran));
51 | need--;
52 | }
53 |
54 | //如果还不够,就从自己身上重复
55 | int size = segmentDatas.size();
56 | for(int i=0;i getAvailableData(PhotoMovie photoMovie, MovieSegment movieSegment);
14 | }
15 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/timer/IMovieTimer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.timer;
2 |
3 | /**
4 | * Created by huangwei on 2015/5/25.
5 | */
6 | public interface IMovieTimer {
7 |
8 | public void start();
9 |
10 | public void pause();
11 |
12 | public void setMovieListener(MovieListener movieListener);
13 |
14 | public int getCurrentPlayTime();
15 |
16 | void setLoop(boolean loop);
17 |
18 | public interface MovieListener {
19 | void onMovieUpdate(int elapsedTime);
20 |
21 | void onMovieStarted();
22 |
23 | void onMoviedPaused();
24 |
25 | void onMovieResumed();
26 |
27 | void onMovieEnd();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/timer/MovieTimer.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.timer;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ValueAnimator;
5 | import android.view.animation.LinearInterpolator;
6 | import com.hw.photomovie.PhotoMovie;
7 |
8 | /**
9 | * Created by yellowcat on 2015/6/12.
10 | */
11 | public class MovieTimer implements IMovieTimer, ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
12 |
13 | private final ValueAnimator mAnimator;
14 |
15 | private MovieListener mMovieListener;
16 |
17 | private long mPausedPlayTime;
18 | private boolean mPaused;
19 |
20 | private PhotoMovie mPhotoMovie;
21 | private boolean mLoop;
22 |
23 | public MovieTimer(PhotoMovie photoMovie) {
24 | mPhotoMovie = photoMovie;
25 |
26 | mAnimator = ValueAnimator.ofInt(0, 1);
27 | mAnimator.setInterpolator(new LinearInterpolator());
28 | mAnimator.addUpdateListener(this);
29 | mAnimator.addListener(this);
30 | mAnimator.setDuration(Long.MAX_VALUE);
31 | }
32 |
33 | public void start() {
34 | if (!mPaused) {
35 | mAnimator.start();
36 | } else {
37 | mAnimator.start();
38 | }
39 | }
40 |
41 | public void pause() {
42 | if (mPaused) {
43 | return;
44 | }
45 | mPaused = true;
46 | mPausedPlayTime = mAnimator.getCurrentPlayTime();
47 | mAnimator.cancel();
48 | }
49 |
50 | @Override
51 | public void setMovieListener(IMovieTimer.MovieListener movieListener) {
52 | this.mMovieListener = movieListener;
53 | }
54 |
55 | @Override
56 | public int getCurrentPlayTime() {
57 | return (int) mPausedPlayTime;
58 | }
59 |
60 | @Override
61 | public void setLoop(boolean loop) {
62 | mLoop = loop;
63 | }
64 |
65 | @Override
66 | public void onAnimationUpdate(ValueAnimator animation) {
67 | if (mPaused || !animation.isRunning()) {
68 | return;
69 | }
70 |
71 | long curTime = animation.getCurrentPlayTime();
72 |
73 | if (curTime >= mPhotoMovie.getDuration()) {
74 | mAnimator.removeUpdateListener(this);
75 | mAnimator.removeListener(this);
76 | mAnimator.end();
77 | if (mMovieListener != null) {
78 | mMovieListener.onMovieEnd();
79 | }
80 | mAnimator.addUpdateListener(this);
81 | mAnimator.addListener(this);
82 | if(mLoop){
83 | mAnimator.start();
84 | }
85 | }else{
86 | if (mMovieListener != null) {
87 | mMovieListener.onMovieUpdate((int) curTime);
88 | }
89 | }
90 | }
91 |
92 | @Override
93 | public void onAnimationStart(Animator animation) {
94 | if (mMovieListener != null) {
95 | if (mPaused) {
96 | mMovieListener.onMovieResumed();
97 | } else {
98 | mMovieListener.onMovieStarted();
99 | }
100 | }
101 | if (mPaused) {
102 | mAnimator.setCurrentPlayTime(mPausedPlayTime);
103 | }
104 | mPaused = false;
105 | mPausedPlayTime = 0;
106 | }
107 |
108 | @Override
109 | public void onAnimationEnd(Animator animation) {
110 | if (mMovieListener != null) {
111 | if (mPaused) {
112 | mMovieListener.onMoviedPaused();
113 | } else {
114 | mMovieListener.onMovieEnd();
115 | }
116 | }
117 | }
118 |
119 | @Override
120 | public void onAnimationCancel(Animator animation) {
121 | mPausedPlayTime = mAnimator.getCurrentPlayTime();
122 | }
123 |
124 | @Override
125 | public void onAnimationRepeat(Animator animation) {
126 |
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/AppResources.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.util;
2 |
3 | import android.content.res.AssetManager;
4 | import android.content.res.Resources;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.InputStreamReader;
12 |
13 | /**
14 | * Created by huangwei on 2015/6/4.
15 | */
16 | public class AppResources {
17 |
18 | private Resources mResources;
19 |
20 | private AppResources() {
21 |
22 | }
23 |
24 | public void init(Resources resources) {
25 | mResources = resources;
26 | }
27 |
28 | public Resources getAppRes() {
29 | if (mResources == null) {
30 | throw new RuntimeException("ApplicationResource never inited.");
31 | }
32 | return mResources;
33 | }
34 |
35 | public float getAppDensity() {
36 | if (mResources == null) {
37 | throw new RuntimeException("ApplicationResource never inited.");
38 | }
39 | return mResources.getDisplayMetrics().density;
40 | }
41 |
42 | public static AppResources getInstance() {
43 | return Holder.INSTANCE;
44 | }
45 |
46 | private static final class Holder {
47 | private static AppResources INSTANCE = new AppResources();
48 | }
49 |
50 | public static String loadShaderFromAssets(String assetsName){
51 | AssetManager am = AppResources.getInstance().getAppRes().getAssets();
52 | StringBuffer stringBuffer = new StringBuffer();
53 | InputStream inputStream = null;
54 | try {
55 | inputStream = am.open(assetsName);
56 | BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
57 | String str = null;
58 | while ((str = br.readLine()) != null) {
59 | stringBuffer.append(str);
60 | }
61 | }catch (IOException e){
62 | e.printStackTrace();
63 | }finally {
64 | if(inputStream!=null) {
65 | try {
66 | inputStream.close();
67 | } catch (IOException e) {
68 | e.printStackTrace();
69 | }
70 | }
71 | }
72 | return stringBuffer.toString();
73 | }
74 |
75 | public static Bitmap loadBitmapFromAssets(String assetsName){
76 | AssetManager am = AppResources.getInstance().getAppRes().getAssets();
77 | InputStream inputStream = null;
78 | try {
79 | inputStream = am.open(assetsName);
80 | return BitmapFactory.decodeStream(inputStream);
81 | }catch (IOException e){
82 | e.printStackTrace();
83 | }finally {
84 | if(inputStream!=null) {
85 | try {
86 | inputStream.close();
87 | } catch (IOException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 | }
92 | return null;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/BitmapUtil.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.util;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.text.TextPaint;
7 |
8 | /**
9 | * Created by huangwei on 2018/10/27.
10 | */
11 | public class BitmapUtil {
12 | public static Bitmap generateBitmap(String text,int textSizePx,int textColor){
13 | TextPaint textPaint = new TextPaint();
14 | textPaint.setTextSize(textSizePx);
15 | textPaint.setColor(textColor);
16 | int width = (int) Math.ceil(textPaint.measureText(text));
17 | Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
18 | int height = (int) Math.ceil(Math.abs(fontMetrics.bottom) + Math.abs(fontMetrics.top));
19 | Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
20 | Canvas canvas = new Canvas(bitmap);
21 | canvas.drawText(text,0,Math.abs(fontMetrics.ascent),textPaint);
22 | return bitmap;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/IntArray.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.hw.photomovie.util;
18 |
19 | public class IntArray {
20 | private static final int INIT_CAPACITY = 8;
21 |
22 | private int mData[] = new int[INIT_CAPACITY];
23 | private int mSize = 0;
24 |
25 | public void add(int value) {
26 | if (mData.length == mSize) {
27 | int temp[] = new int[mSize + mSize];
28 | System.arraycopy(mData, 0, temp, 0, mSize);
29 | mData = temp;
30 | }
31 | mData[mSize++] = value;
32 | }
33 |
34 | public int removeLast() {
35 | mSize--;
36 | return mData[mSize];
37 | }
38 |
39 | public int size() {
40 | return mSize;
41 | }
42 |
43 | // For testing only
44 | public int[] toArray(int[] result) {
45 | if (result == null || result.length < mSize) {
46 | result = new int[mSize];
47 | }
48 | System.arraycopy(mData, 0, result, 0, mSize);
49 | return result;
50 | }
51 |
52 | public int[] getInternalArray() {
53 | return mData;
54 | }
55 |
56 | public void clear() {
57 | mSize = 0;
58 | if (mData.length != INIT_CAPACITY) {
59 | mData = new int[INIT_CAPACITY];
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/MLog.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.util;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Created by huangwei on 2015/5/25.
7 | */
8 | public class MLog {
9 |
10 | public static final boolean DEBUG = true;
11 |
12 | public static void i(String tag, String msg){
13 | if(DEBUG){
14 | Log.i(tag,msg);
15 | }
16 | }
17 |
18 | public static void v(String tag, String msg){
19 | if(DEBUG){
20 | Log.v(tag, msg);
21 | }
22 | }
23 |
24 | public static void d(String tag, String msg){
25 | if(DEBUG){
26 | Log.d(tag, msg);
27 | }
28 | }
29 |
30 | public static void w(String tag, String msg,Throwable t){
31 | if(DEBUG){
32 | Log.w(tag, msg,t);
33 | }
34 | }
35 |
36 | public static void w(String tag, String msg){
37 | if(DEBUG){
38 | Log.w(tag, msg);
39 | }
40 | }
41 |
42 | public static void e(String tag, String msg){
43 | if(DEBUG){
44 | Log.e(tag, msg);
45 | }
46 | }
47 |
48 | public static void e(String tag, String msg,Throwable t){
49 | if(DEBUG){
50 | Log.e(tag,msg,t);
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/PhotoUtil.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.util;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Rect;
5 | import android.graphics.RectF;
6 |
7 | /**
8 | * Created by huangwei on 14-12-31.
9 | */
10 | public class PhotoUtil {
11 | /**
12 | * 根据toWidth和toHieght,返回适用于bitmap的srcRect,只裁剪不压缩
13 | * 裁剪方式为裁上下或两边
14 | *
15 | * @param srcRect
16 | * @param bitmapWidth
17 | * @param bitmapHeight
18 | * @param toWidth
19 | * @param toHeight
20 | * @return
21 | */
22 | public static Rect getCroppedRect(Rect srcRect, int bitmapWidth, int bitmapHeight, float toWidth, float toHeight) {
23 | if (srcRect == null) {
24 | srcRect = new Rect();
25 | }
26 | float rate = toWidth / toHeight;
27 | float bitmapRate = bitmapWidth / (float) bitmapHeight;
28 |
29 | if (Math.abs(rate - bitmapRate) < 0.01) {
30 |
31 | srcRect.left = 0;
32 | srcRect.top = 0;
33 | srcRect.right = bitmapWidth;
34 | srcRect.bottom = bitmapHeight;
35 | } else if (bitmapRate > rate) {
36 | //裁两边
37 | float cutRate = toHeight / (float) bitmapHeight;
38 | float toCutWidth = cutRate * bitmapWidth - toWidth;
39 | float toCutWidthReal = toCutWidth / cutRate;
40 |
41 | srcRect.left = (int) (toCutWidthReal / 2);
42 | srcRect.top = 0;
43 | srcRect.right = bitmapWidth - (int) (toCutWidthReal / 2);
44 | srcRect.bottom = bitmapHeight;
45 | } else {
46 | //裁上下
47 | float cutRate = toWidth / (float) bitmapWidth;
48 | float toCutHeight = cutRate * bitmapHeight - toHeight;
49 | float toCutHeightReal = toCutHeight / cutRate;
50 |
51 | srcRect.left = 0;
52 | srcRect.top = (int) (toCutHeightReal / 2);
53 | srcRect.right = bitmapWidth;
54 | srcRect.bottom = bitmapHeight - (int) (toCutHeightReal / 2);
55 |
56 | }
57 | return srcRect;
58 | }
59 |
60 | /**
61 | * 计算图片根据高宽居中情况下的目标显示区域
62 | *
63 | * @return
64 | */
65 | public static RectF getFitCenterRect(RectF dstRect, int bitmapWidth, int bitmapHeight, int outWidth, int outHeight) {
66 | if (dstRect == null) {
67 | dstRect = new RectF();
68 | }
69 | float rate = outWidth / outHeight;
70 | float bitmapRate = bitmapWidth / (float) bitmapHeight;
71 |
72 | if (Math.abs(rate - bitmapRate) < 0.01) {
73 | dstRect.left = 0;
74 | dstRect.top = 0;
75 | dstRect.right = outWidth;
76 | dstRect.bottom = outHeight;
77 | } else if (bitmapRate > rate) {
78 | //宽满,上下留白
79 | int showWidth = outWidth;
80 | int showHeight = (int) (showWidth / bitmapRate);
81 |
82 | dstRect.left = 0;
83 | dstRect.right = outWidth;
84 | dstRect.top = outHeight / 2 - showHeight / 2;
85 | dstRect.bottom = outHeight / 2 + showHeight / 2;
86 | } else {
87 | //高满,左右留白
88 | int showHeight = outHeight;
89 | int showWidth = (int) (showHeight * bitmapRate);
90 |
91 | dstRect.left = outWidth / 2 - showWidth / 2;
92 | dstRect.right = outWidth / 2 + showWidth / 2;
93 | dstRect.top = 0;
94 | dstRect.bottom = outHeight;
95 | }
96 | return dstRect;
97 | }
98 |
99 |
100 | public static Bitmap createBitmapOrNull(int width, int height, Bitmap.Config config) {
101 | try {
102 | return Bitmap.createBitmap(width, height, config);
103 | } catch (OutOfMemoryError e) {
104 | return null;
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/ScaleType.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.util;
2 |
3 | /**
4 | * Created by huangwei on 2015/6/4.
5 | */
6 | public enum ScaleType {
7 | /**
8 | * 左右上下裁剪填满输出窗口
9 | */
10 | CENTER_CROP,
11 | /**
12 | * 不管比例拉伸填满输出窗口
13 | */
14 | FIT_XY,
15 | /**
16 | * 居中,同时填满输出窗口的宽或者高
17 | */
18 | FIT_CENTER
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/SystemPropertiesUtil.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.util;
2 |
3 | import java.lang.reflect.InvocationTargetException;
4 | import java.lang.reflect.Method;
5 |
6 | /**
7 | * Created by huangwei on 2018/9/6 0006.
8 | */
9 | public class SystemPropertiesUtil {
10 |
11 | public static int getInt(String key, int defaultValue) {
12 | try {
13 | return Integer.parseInt(get(key));
14 | } catch (Exception e) {
15 | e.printStackTrace();
16 | return defaultValue;
17 | }
18 | }
19 |
20 | public static int getInt(String key) {
21 | return Integer.parseInt(get(key));
22 | }
23 |
24 | public static String get(String key) {
25 | String result = "";
26 | try {
27 | Class> c = Class.forName("android.os.SystemProperties");
28 |
29 | Method get = c.getMethod("get", String.class);
30 | result = (String) get.invoke(c, key);
31 |
32 | } catch (ClassNotFoundException e) {
33 | // TODO Auto-generated catch block
34 | e.printStackTrace();
35 | } catch (NoSuchMethodException e) {
36 | // TODO Auto-generated catch block
37 | e.printStackTrace();
38 | } catch (IllegalAccessException e) {
39 | // TODO Auto-generated catch block
40 | e.printStackTrace();
41 | } catch (IllegalArgumentException e) {
42 | // TODO Auto-generated catch block
43 | e.printStackTrace();
44 | } catch (InvocationTargetException e) {
45 | // TODO Auto-generated catch block
46 | e.printStackTrace();
47 | }
48 | return result;
49 | }
50 |
51 | /**
52 | * Set the value for the given key.
53 | *
54 | * @throws IllegalArgumentException if the key exceeds 32 characters
55 | * @throws IllegalArgumentException if the value exceeds 92 characters
56 | */
57 | public static void set(String key, String val) {
58 | try {
59 | Class> c = Class.forName("android.os.SystemProperties");
60 | Method set = c.getMethod("set", String.class, String.class);
61 | set.invoke(c, key, val);
62 | } catch (ClassNotFoundException e) {
63 | // TODO Auto-generated catch block
64 | e.printStackTrace();
65 | } catch (NoSuchMethodException e) {
66 | // TODO Auto-generated catch block
67 | e.printStackTrace();
68 | } catch (IllegalAccessException e) {
69 | // TODO Auto-generated catch block
70 | e.printStackTrace();
71 | } catch (IllegalArgumentException e) {
72 | // TODO Auto-generated catch block
73 | e.printStackTrace();
74 | } catch (InvocationTargetException e) {
75 | // TODO Auto-generated catch block
76 | e.printStackTrace();
77 | }
78 |
79 | }
80 |
81 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/hw/photomovie/util/stackblur/BlurProcess.java:
--------------------------------------------------------------------------------
1 | package com.hw.photomovie.util.stackblur;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | interface BlurProcess {
6 | /**
7 | * Process the given image, blurring by the supplied radius.
8 | * If radius is 0, this will return original
9 | * @param original the bitmap to be blurred
10 | * @param radius the radius in pixels to blur the image
11 | * @return the blurred version of the image.
12 | */
13 | public Bitmap blur(Bitmap original, float radius);
14 | }
15 |
--------------------------------------------------------------------------------
/library/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | library
3 |
4 | Hello world!
5 | Settings
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/readme/PhotoMovie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowcath/PhotoMovie/ed952bb6c9cbb556ae138d5c32bcc09b61bf8be6/readme/PhotoMovie.png
--------------------------------------------------------------------------------
/readme/filter.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowcath/PhotoMovie/ed952bb6c9cbb556ae138d5c32bcc09b61bf8be6/readme/filter.gif
--------------------------------------------------------------------------------
/readme/gradient.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowcath/PhotoMovie/ed952bb6c9cbb556ae138d5c32bcc09b61bf8be6/readme/gradient.gif
--------------------------------------------------------------------------------
/readme/gradient_timeline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowcath/PhotoMovie/ed952bb6c9cbb556ae138d5c32bcc09b61bf8be6/readme/gradient_timeline.png
--------------------------------------------------------------------------------
/readme/transfer.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yellowcath/PhotoMovie/ed952bb6c9cbb556ae138d5c32bcc09b61bf8be6/readme/transfer.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library', ':dynamicdemo'
2 |
--------------------------------------------------------------------------------