implemented initial effects

pull/527/head
Suneet Agrawal 6 years ago
parent 6f8b3e2297
commit ffdd071b96
  1. 71
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  2. 41
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/egl/EglViewport.java
  3. 6
      cameraview/src/main/java/com/otaliastudios/cameraview/preview/GlCameraPreview.java
  4. 52
      cameraview/src/main/java/com/otaliastudios/cameraview/shadereffects/ShaderEffectFactory.java
  5. 13
      cameraview/src/main/java/com/otaliastudios/cameraview/shadereffects/effects/NoEffect.java
  6. 23
      cameraview/src/main/java/com/otaliastudios/cameraview/shadereffects/effects/SharpnessEffect.java
  7. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/shadereffects/effects/TemperatureEffect.java
  8. 11
      cameraview/src/main/java/com/otaliastudios/cameraview/shadereffects/effects/TintEffect.java
  9. 20
      cameraview/src/main/java/com/otaliastudios/cameraview/shadereffects/effects/VignetteEffect.java

@ -4,12 +4,6 @@ import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import android.content.Context; import android.content.Context;
import android.content.ContextWrapper; import android.content.ContextWrapper;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
@ -23,9 +17,6 @@ import android.opengl.GLSurfaceView;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -33,27 +24,35 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import com.otaliastudios.cameraview.controls.Audio; import com.otaliastudios.cameraview.controls.Audio;
import com.otaliastudios.cameraview.controls.Control; import com.otaliastudios.cameraview.controls.Control;
import com.otaliastudios.cameraview.controls.ControlParser; import com.otaliastudios.cameraview.controls.ControlParser;
import com.otaliastudios.cameraview.controls.Engine; import com.otaliastudios.cameraview.controls.Engine;
import com.otaliastudios.cameraview.controls.Facing; import com.otaliastudios.cameraview.controls.Facing;
import com.otaliastudios.cameraview.controls.Flash; import com.otaliastudios.cameraview.controls.Flash;
import com.otaliastudios.cameraview.engine.Camera2Engine;
import com.otaliastudios.cameraview.engine.offset.Reference;
import com.otaliastudios.cameraview.markers.MarkerLayout;
import com.otaliastudios.cameraview.engine.Camera1Engine;
import com.otaliastudios.cameraview.engine.CameraEngine;
import com.otaliastudios.cameraview.frame.Frame;
import com.otaliastudios.cameraview.frame.FrameProcessor;
import com.otaliastudios.cameraview.gesture.Gesture;
import com.otaliastudios.cameraview.gesture.GestureAction;
import com.otaliastudios.cameraview.controls.Grid; import com.otaliastudios.cameraview.controls.Grid;
import com.otaliastudios.cameraview.controls.Hdr; import com.otaliastudios.cameraview.controls.Hdr;
import com.otaliastudios.cameraview.controls.Mode; import com.otaliastudios.cameraview.controls.Mode;
import com.otaliastudios.cameraview.controls.Preview; import com.otaliastudios.cameraview.controls.Preview;
import com.otaliastudios.cameraview.controls.VideoCodec; import com.otaliastudios.cameraview.controls.VideoCodec;
import com.otaliastudios.cameraview.controls.WhiteBalance; import com.otaliastudios.cameraview.controls.WhiteBalance;
import com.otaliastudios.cameraview.engine.Camera1Engine;
import com.otaliastudios.cameraview.engine.Camera2Engine;
import com.otaliastudios.cameraview.engine.CameraEngine;
import com.otaliastudios.cameraview.engine.offset.Reference;
import com.otaliastudios.cameraview.frame.Frame;
import com.otaliastudios.cameraview.frame.FrameProcessor;
import com.otaliastudios.cameraview.gesture.Gesture;
import com.otaliastudios.cameraview.gesture.GestureAction;
import com.otaliastudios.cameraview.gesture.GestureFinder; import com.otaliastudios.cameraview.gesture.GestureFinder;
import com.otaliastudios.cameraview.gesture.GestureParser; import com.otaliastudios.cameraview.gesture.GestureParser;
import com.otaliastudios.cameraview.gesture.PinchGestureFinder; import com.otaliastudios.cameraview.gesture.PinchGestureFinder;
@ -63,6 +62,9 @@ import com.otaliastudios.cameraview.internal.GridLinesLayout;
import com.otaliastudios.cameraview.internal.utils.CropHelper; import com.otaliastudios.cameraview.internal.utils.CropHelper;
import com.otaliastudios.cameraview.internal.utils.OrientationHelper; import com.otaliastudios.cameraview.internal.utils.OrientationHelper;
import com.otaliastudios.cameraview.internal.utils.WorkerHandler; import com.otaliastudios.cameraview.internal.utils.WorkerHandler;
import com.otaliastudios.cameraview.markers.AutoFocusMarker;
import com.otaliastudios.cameraview.markers.AutoFocusTrigger;
import com.otaliastudios.cameraview.markers.MarkerLayout;
import com.otaliastudios.cameraview.markers.MarkerParser; import com.otaliastudios.cameraview.markers.MarkerParser;
import com.otaliastudios.cameraview.overlay.OverlayLayout; import com.otaliastudios.cameraview.overlay.OverlayLayout;
import com.otaliastudios.cameraview.preview.CameraPreview; import com.otaliastudios.cameraview.preview.CameraPreview;
@ -70,14 +72,15 @@ import com.otaliastudios.cameraview.preview.GlCameraPreview;
import com.otaliastudios.cameraview.preview.SurfaceCameraPreview; import com.otaliastudios.cameraview.preview.SurfaceCameraPreview;
import com.otaliastudios.cameraview.preview.TextureCameraPreview; import com.otaliastudios.cameraview.preview.TextureCameraPreview;
import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect; import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
import com.otaliastudios.cameraview.shadereffects.effects.BlackAndWhiteEffect; import com.otaliastudios.cameraview.shadereffects.ShaderEffectFactory;
import com.otaliastudios.cameraview.shadereffects.effects.SharpnessEffect;
import com.otaliastudios.cameraview.shadereffects.effects.TemperatureEffect;
import com.otaliastudios.cameraview.shadereffects.effects.TintEffect;
import com.otaliastudios.cameraview.size.AspectRatio; import com.otaliastudios.cameraview.size.AspectRatio;
import com.otaliastudios.cameraview.size.Size; import com.otaliastudios.cameraview.size.Size;
import com.otaliastudios.cameraview.size.SizeSelector; import com.otaliastudios.cameraview.size.SizeSelector;
import com.otaliastudios.cameraview.size.SizeSelectorParser; import com.otaliastudios.cameraview.size.SizeSelectorParser;
import com.otaliastudios.cameraview.size.SizeSelectors; import com.otaliastudios.cameraview.size.SizeSelectors;
import com.otaliastudios.cameraview.markers.AutoFocusMarker;
import com.otaliastudios.cameraview.markers.AutoFocusTrigger;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -88,7 +91,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
import static android.view.View.MeasureSpec.AT_MOST; import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.UNSPECIFIED; import static android.view.View.MeasureSpec.UNSPECIFIED;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
/** /**
@ -580,8 +582,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
if( MotionEvent.ACTION_UP == event.getAction()) { if( MotionEvent.ACTION_UP == event.getAction()) {
Log.d("Suneet Agrawal", "onTouchEvent " + event.getAction()); Log.d("Suneet Agrawal", "onTouchEvent " + event.getAction());
BlackAndWhiteEffect effect = new BlackAndWhiteEffect(); //BlackAndWhiteEffect effect = new BlackAndWhiteEffect();
changeEffect(effect); changeEffect(ShaderEffectFactory.ShaderEffects.SHARPNESS_EFFECT);
} }
return true; return true;
@ -2144,7 +2146,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
//region Effects //region Effects
public GLSurfaceView getCurrentPreviewingGlSurfaceView(){ public GLSurfaceView getCurrentPreviewingGlSurfaceView() {
if (mCameraPreview instanceof GlCameraPreview) { if (mCameraPreview instanceof GlCameraPreview) {
return ((GlCameraPreview) mCameraPreview).getView(); return ((GlCameraPreview) mCameraPreview).getView();
} }
@ -2153,12 +2155,23 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return null; return null;
} }
public void changeEffect(BaseShaderEffect shader) { public void changeEffect(ShaderEffectFactory.ShaderEffects effect) {
if (mCameraPreview instanceof GlCameraPreview) { if (mCameraPreview instanceof GlCameraPreview) {
String effect = shader.getFragmentShader(); GLSurfaceView previewingSurfaceView = getCurrentPreviewingGlSurfaceView();
((GlCameraPreview) mCameraPreview).setEffectFragmentShader(effect); if (previewingSurfaceView != null) {
BaseShaderEffect shaderEffect = ShaderEffectFactory.getShaderFromFactory(effect, previewingSurfaceView);
((SharpnessEffect)shaderEffect).setSharpnessValue(1.0f);
((GlCameraPreview) mCameraPreview).setShaderEffect(shaderEffect);
}
} else {
LOG.w("changeEffect", "changeEffect is supported only for GLSurfaceView");
}
}
//doInstantiatePreview(); public void changeEffect(BaseShaderEffect shaderEffect) {
if (mCameraPreview instanceof GlCameraPreview) {
((GlCameraPreview) mCameraPreview).setShaderEffect(shaderEffect);
} else { } else {
LOG.w("changeEffect", "changeEffect is supported only for GLSurfaceView"); LOG.w("changeEffect", "changeEffect is supported only for GLSurfaceView");
} }

@ -5,6 +5,8 @@ import android.opengl.GLES11Ext;
import android.opengl.GLES20; import android.opengl.GLES20;
import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
import com.otaliastudios.cameraview.shadereffects.effects.NoEffect;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
@ -74,19 +76,38 @@ public class EglViewport extends EglElement {
// private int muTexOffsetLoc; // Used for filtering // private int muTexOffsetLoc; // Used for filtering
// private int muColorAdjustLoc; // Used for filtering // private int muColorAdjustLoc; // Used for filtering
private String vertexShader = SIMPLE_VERTEX_SHADER; private String mVertexShader = SIMPLE_VERTEX_SHADER;
private String fragmentShader = SIMPLE_FRAGMENT_SHADER; private String mFragmentShader = SIMPLE_FRAGMENT_SHADER;
private boolean isShaderChanged = false; private BaseShaderEffect mShaderEffect;
private boolean mIsShaderChanged = false;
public EglViewport() { public EglViewport() {
mTextureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES; mTextureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES;
mShaderEffect = new NoEffect();
initProgram(); initProgram();
} }
private void initProgram(){ private void initProgram(){
mProgramHandle = createProgram(vertexShader, fragmentShader); release();
mTextureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES;
mProgramHandle = createProgram(mShaderEffect.getVertextShader(), mShaderEffect.getFragmentShader());
maPositionLocation = GLES20.glGetAttribLocation(mProgramHandle, mShaderEffect.getPositionVariableName());
checkLocation(maPositionLocation, mShaderEffect.getPositionVariableName());
maTextureCoordLocation = GLES20.glGetAttribLocation(mProgramHandle, mShaderEffect.getTexttureCoordinateVariableName());
checkLocation(maTextureCoordLocation, mShaderEffect.getTexttureCoordinateVariableName());
muMVPMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, mShaderEffect.getMVPMatrixVariableName());
checkLocation(muMVPMatrixLocation, mShaderEffect.getMVPMatrixVariableName());
muTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, mShaderEffect.getTextureMatrixVariableName());
checkLocation(muTexMatrixLocation, mShaderEffect.getTextureMatrixVariableName());
/*mProgramHandle = createProgram(mVertexShader, mFragmentShader);
maPositionLocation = GLES20.glGetAttribLocation(mProgramHandle, "aPosition"); maPositionLocation = GLES20.glGetAttribLocation(mProgramHandle, "aPosition");
checkLocation(maPositionLocation, "aPosition"); checkLocation(maPositionLocation, "aPosition");
@ -95,7 +116,7 @@ public class EglViewport extends EglElement {
muMVPMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uMVPMatrix"); muMVPMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uMVPMatrix");
checkLocation(muMVPMatrixLocation, "uMVPMatrix"); checkLocation(muMVPMatrixLocation, "uMVPMatrix");
muTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uTexMatrix"); muTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uTexMatrix");
checkLocation(muTexMatrixLocation, "uTexMatrix"); checkLocation(muTexMatrixLocation, "uTexMatrix");*/
// Stuff from Drawable2d.FULL_RECTANGLE // Stuff from Drawable2d.FULL_RECTANGLE
} }
@ -127,9 +148,9 @@ public class EglViewport extends EglElement {
return texId; return texId;
} }
public void changeEffectFragmentShader(String fragmentShader){ public void changeShaderEffect(BaseShaderEffect shaderEffect){
this.fragmentShader = fragmentShader; this.mShaderEffect = shaderEffect;
isShaderChanged = true; mIsShaderChanged = true;
} }
@ -157,9 +178,9 @@ public class EglViewport extends EglElement {
FloatBuffer vertexBuffer, FloatBuffer vertexBuffer,
FloatBuffer texBuffer) { FloatBuffer texBuffer) {
if (isShaderChanged){ if (mIsShaderChanged){
initProgram(); initProgram();
isShaderChanged = false; mIsShaderChanged = false;
} }
check("draw start"); check("draw start");

@ -7,7 +7,6 @@ import android.opengl.Matrix;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.View; import android.view.View;
@ -16,6 +15,7 @@ import android.view.ViewGroup;
import com.otaliastudios.cameraview.R; import com.otaliastudios.cameraview.R;
import com.otaliastudios.cameraview.internal.egl.EglViewport; import com.otaliastudios.cameraview.internal.egl.EglViewport;
import com.otaliastudios.cameraview.internal.utils.Op; import com.otaliastudios.cameraview.internal.utils.Op;
import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
import com.otaliastudios.cameraview.size.AspectRatio; import com.otaliastudios.cameraview.size.AspectRatio;
import java.util.Collections; import java.util.Collections;
@ -310,7 +310,7 @@ public class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture
return new Renderer(); return new Renderer();
} }
public void setEffectFragmentShader(String fragmentShader){ public void setShaderEffect(BaseShaderEffect shaderEffect){
mOutputViewport.changeEffectFragmentShader(fragmentShader); mOutputViewport.changeShaderEffect(shaderEffect);
} }
} }

@ -0,0 +1,52 @@
package com.otaliastudios.cameraview.shadereffects;
import android.opengl.GLSurfaceView;
import com.otaliastudios.cameraview.shadereffects.effects.BlackAndWhiteEffect;
import com.otaliastudios.cameraview.shadereffects.effects.NoEffect;
import com.otaliastudios.cameraview.shadereffects.effects.SharpnessEffect;
import com.otaliastudios.cameraview.shadereffects.effects.TemperatureEffect;
import com.otaliastudios.cameraview.shadereffects.effects.TintEffect;
import com.otaliastudios.cameraview.shadereffects.effects.VignetteEffect;
public class ShaderEffectFactory {
public enum ShaderEffects {
BLACK_AND_WHITE_EFFECT,
SHARPNESS_EFFECT,
TEMPERATURE_EFFECT,
TINT_EFFECT,
VIGNETTE_EFFECT
}
public static BaseShaderEffect getShaderFromFactory(ShaderEffects effect, GLSurfaceView glSurfaceView) {
BaseShaderEffect shaderEffect;
switch (effect) {
case BLACK_AND_WHITE_EFFECT:
shaderEffect = new BlackAndWhiteEffect();
break;
case SHARPNESS_EFFECT:
shaderEffect = new SharpnessEffect(glSurfaceView);
break;
case TEMPERATURE_EFFECT:
shaderEffect = new TemperatureEffect();
break;
case TINT_EFFECT:
shaderEffect = new TintEffect();
break;
case VIGNETTE_EFFECT:
shaderEffect = new VignetteEffect(glSurfaceView);
break;
default:
shaderEffect = new NoEffect();
}
return shaderEffect;
}
}

@ -23,6 +23,19 @@ public class NoEffect extends BaseShaderEffect {
+ " gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + " gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
+ "}\n"; + "}\n";
//This fragment shader is copied from black and white,
//this is for testing purpose and need to be removed once testing is done.
/*String shader = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "varying vec2 vTextureCoord;\n"
+ "uniform samplerExternalOES sTexture;\n" + "void main() {\n"
+ " vec4 color = texture2D(sTexture, vTextureCoord);\n"
+ " float colorR = (color.r + color.g + color.b) / 3.0;\n"
+ " float colorG = (color.r + color.g + color.b) / 3.0;\n"
+ " float colorB = (color.r + color.g + color.b) / 3.0;\n"
+ " gl_FragColor = vec4(colorR, colorG, colorB, color.a);\n"
+ "}\n";*/
return shader; return shader;
} }

@ -9,20 +9,27 @@ import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
public class SharpnessEffect extends BaseShaderEffect { public class SharpnessEffect extends BaseShaderEffect {
private int mWidth; private int mWidth;
private int mHeight; private int mHeight;
private float scale = 0f; private float scale = 0.5f;
/** /**
* Initialize Effect * Initialize Effect
* *
* @param scale Float, between 0 and 1. 0 means no change. *
*/
public SharpnessEffect(GLSurfaceView glSurfaceView) {
this.mGlSurfaceView = glSurfaceView;
}
/**
* @param value Float, between 0 and 1. 0 means no change.
*/ */
public SharpnessEffect(float scale) { public void setSharpnessValue(float value){
if (scale < 0.0f) if (value < 0.0f)
scale = 0.0f; value = 0.0f;
if (scale > 1.0f) if (value > 1.0f)
scale = 1.0f; value = 1.0f;
this.scale = scale; this.scale = value;
} }
/** /**

@ -10,17 +10,20 @@ public class TemperatureEffect extends BaseShaderEffect {
/** /**
* Initialize Effect * Initialize Effect
* */
public TemperatureEffect() {
}
/**
* @param scale Float, between 0 and 1, with 0 indicating cool, and 1 * @param scale Float, between 0 and 1, with 0 indicating cool, and 1
* indicating warm. A value of of 0.5 indicates no change. * indicating warm. A value of of 0.5 indicates no change.
*/ */
public TemperatureEffect(float scale) { public void setTemperatureScale(float scale){
if (scale < 0.0f) if (scale < 0.0f)
scale = 0.0f; scale = 0.0f;
if (scale > 1.0f) if (scale > 1.0f)
scale = 1.0f; scale = 1.0f;
this.scale = scale; this.scale = scale;
} }
@Override @Override

@ -9,17 +9,16 @@ import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
* Tints the preview with specified color.. * Tints the preview with specified color..
*/ */
public class TintEffect extends BaseShaderEffect { public class TintEffect extends BaseShaderEffect {
private int mTint = 0xFF0000FF; private int mTint = 0xFFFF0000;
/** /**
* Initialize Effect * Initialize Effect
*
* @param color Integer, representing an ARGB color with 8 bits per channel.
* May be created using Color class.
*/ */
public TintEffect(int color) { public TintEffect() {
this.mTint = color; }
public void setTintColor(int color){
this.mTint = color;
} }
@Override @Override

@ -11,21 +11,33 @@ import com.otaliastudios.cameraview.shadereffects.BaseShaderEffect;
public class VignetteEffect extends BaseShaderEffect { public class VignetteEffect extends BaseShaderEffect {
private int mWidth = 0; private int mWidth = 0;
private int mHeight = 0; private int mHeight = 0;
private float mScale = 0f; private float mScale = 0.85f;
private final float mShade = 0.85f; private float mShade = 0.5f;
/** /**
* Initialize Effect * Initialize Effect
* *
* @param scale Float, between 0 and 1. 0 means no change. * @param glSurfaceView GLSurfaceView
*/ */
public VignetteEffect(float scale) { public VignetteEffect(GLSurfaceView glSurfaceView) {
this.mGlSurfaceView = glSurfaceView;
}
public void setVignetteEffectScale(float scale){
if (scale < 0.0f) if (scale < 0.0f)
scale = 0.0f; scale = 0.0f;
if (scale > 1.0f) if (scale > 1.0f)
scale = 1.0f; scale = 1.0f;
this.mScale = scale; this.mScale = scale;
}
public void setVignetteEffectShade(float shade){
if (shade < 0.0f)
shade = 0.0f;
if (shade > 1.0f)
shade = 1.0f;
this.mShade = shade;
} }
/** /**

Loading…
Cancel
Save