Repository: yangmingchuan/CameraMaster
Branch: master
Commit: 5340823cd85f
Files: 103
Total size: 501.9 KB
Directory structure:
gitextract_43xg_rh9/
├── .gitignore
├── .idea/
│ ├── caches/
│ │ └── build_file_checksums.ser
│ ├── codeStyles/
│ │ └── Project.xml
│ ├── gradle.xml
│ ├── inspectionProfiles/
│ │ └── Project_Default.xml
│ ├── jarRepositories.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── camera/
│ │ └── cn/
│ │ └── cameramaster/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── web/
│ │ │ ├── css/
│ │ │ │ └── login.css
│ │ │ ├── index.html
│ │ │ └── login.html
│ │ ├── java/
│ │ │ └── camera/
│ │ │ └── cn/
│ │ │ └── cameramaster/
│ │ │ ├── OpenReceiver.java
│ │ │ ├── adapter/
│ │ │ │ ├── EffectAdapter.java
│ │ │ │ ├── MenuAdapter.java
│ │ │ │ └── SenseAdapter.java
│ │ │ ├── base/
│ │ │ │ ├── App.java
│ │ │ │ └── BaseActivity.java
│ │ │ ├── bean/
│ │ │ │ └── Lab.java
│ │ │ ├── filter/
│ │ │ │ ├── AFilter.java
│ │ │ │ └── TextureFilter.java
│ │ │ ├── server/
│ │ │ │ ├── AnyEventType.java
│ │ │ │ ├── CoreService.java
│ │ │ │ ├── ServerManager.java
│ │ │ │ ├── TestController.java
│ │ │ │ ├── component/
│ │ │ │ │ └── LoggerInterceptor.java
│ │ │ │ ├── model/
│ │ │ │ │ └── UserInfo.java
│ │ │ │ └── util/
│ │ │ │ ├── FileUtils.java
│ │ │ │ └── NetUtils.java
│ │ │ ├── ui/
│ │ │ │ ├── Camera2Activity.java
│ │ │ │ ├── CameraActivity.java
│ │ │ │ ├── CameraSurfaceViewActivity.java
│ │ │ │ ├── CameraVideoActivity.java
│ │ │ │ ├── GoogleCameraActivity.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── ShowPicActivity.java
│ │ │ ├── util/
│ │ │ │ ├── AppConstant.java
│ │ │ │ ├── BitmapUtils.java
│ │ │ │ ├── Camera2Util.java
│ │ │ │ ├── CameraUtil.java
│ │ │ │ ├── CameraV2.java
│ │ │ │ ├── CompareSizesByArea.java
│ │ │ │ ├── FilterEngine.java
│ │ │ │ ├── LabUtil.java
│ │ │ │ ├── MatrixUtils.java
│ │ │ │ ├── Utils.java
│ │ │ │ ├── cameravideo/
│ │ │ │ │ ├── CameraHelper.java
│ │ │ │ │ ├── CoordinateTransformer.java
│ │ │ │ │ ├── ICamera2.java
│ │ │ │ │ ├── IVideoControl.java
│ │ │ │ │ └── VideoPlayer.java
│ │ │ │ └── render/
│ │ │ │ └── CameraV2Renderer.java
│ │ │ └── view/
│ │ │ ├── AnimationTextView.java
│ │ │ ├── AutoFitTextureView.java
│ │ │ ├── AutoLocateHorizontalView.java
│ │ │ ├── AutoTextureView.java
│ │ │ ├── AwbSeekBar.java
│ │ │ ├── AwbSeekBarChangeListener.java
│ │ │ ├── CameraV2GLSurfaceView.java
│ │ │ ├── ShowSurfaceView.java
│ │ │ └── SleepThread.java
│ │ └── res/
│ │ ├── anim/
│ │ │ ├── alpha_in.xml
│ │ │ └── alpha_out.xml
│ │ ├── drawable/
│ │ │ ├── ic_camera.xml
│ │ │ ├── ic_fouces.xml
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── ic_launcher_camera.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ ├── activity_camera.xml
│ │ │ ├── activity_camera2.xml
│ │ │ ├── activity_camera_sv.xml
│ │ │ ├── activity_camera_video.xml
│ │ │ ├── activity_google_camera.xml
│ │ │ ├── activity_look_camera.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_show_pic.xml
│ │ │ ├── item_age.xml
│ │ │ └── item_rv_text.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── mipmap-xhdpi/
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── icon_back.xml
│ │ ├── raw/
│ │ │ ├── base_fragment_shader.glsl
│ │ │ └── base_vertex_shader.glsl
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── xml/
│ │ └── file_paths.xml
│ └── test/
│ └── java/
│ └── camera/
│ └── cn/
│ └── cameramaster/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
================================================
FILE: .idea/codeStyles/Project.xml
================================================

* 问题:加上后确实没有卡顿现象 但是截图会是 黑屏
*/
private void bindfbo() {
GLES20.glGenFramebuffers(1, fFrame, 0);
GLES20.glGenTextures(1, fTexture, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fTexture[0]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
surfaceWidth, surfaceHeight, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glBindFramebuffer(GL_FRAMEBUFFER, fFrame[0]);
GLES20.glFramebufferTexture2D(GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, fTexture[0], 0);
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) {
throw new RuntimeException("status:" + status + ", hex:" + Integer.toHexString(status));
}
}
private void unbindfbo() {
GLES20.glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLES20.glDeleteTextures(1, fTexture, 0);
GLES20.glDeleteFramebuffers(1, fFrame, 0);
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/AnimationTextView.java
================================================
package camera.cn.cameramaster.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.animation.Animation;
import android.widget.TextView;
/**
* 文字显示 一秒后消失
*/
@SuppressLint("AppCompatCustomView")
public class AnimationTextView extends TextView {
private Handler mMainHandler;
private Animation mAnimation;
/**
* 防止又换了个text,但是上次哪个还没有消失即将小时就把新的text的给消失了
*/
public int mTimes = 0;
public AnimationTextView(Context context) {
super(context);
}
public AnimationTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AnimationTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public AnimationTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public void setmMainHandler(Handler mMainHandler) {
this.mMainHandler = mMainHandler;
}
public void setmAnimation(Animation mAnimation) {
this.mAnimation = mAnimation;
}
public void start(String text, int message) {
if (mAnimation == null || mMainHandler == null) {
return;
}
this.setVisibility(VISIBLE);
mTimes++;
this.setText(text);
this.startAnimation(mAnimation);
new Thread(new SleepThread(mMainHandler, message, 1000, Integer.valueOf(mTimes))).start();
}
public void stop() {
this.setVisibility(GONE);
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/AutoFitTextureView.java
================================================
package camera.cn.cameramaster.view;
import android.content.Context;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.TextureView;
/**
* 自定义 TextureView
* 重新计算预览宽高
*
* @fileName: AutoFitTextureView
* @date: 2019/1/28 17:00
* @author: ymc
* @QQ:745612618
*/
public class AutoFitTextureView extends TextureView {
private int mRatioWidth = 0;
private int mRatioHeight = 0;
public AutoFitTextureView(Context context) {
this(context, null);
}
public AutoFitTextureView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 设置此视图的纵横比。将根据比率测量视图的大小 根据参数计算。注意,参数的实际大小无关紧要
* 调用setAspectRatio(2,3)和setAspectRatio(4,6)会产生相同的结果。
*
* @param width Relative horizontal size
* @param height Relative vertical size
*/
public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
float mRatio = (float) mRatioWidth / (float) mRatioHeight; //算出相机的缩放比例
float w = mRatio * getHeight();
float scale;
if (w > getWidth())
scale = w / (float) getWidth();
else
scale = (float) getWidth() / w;
Matrix matrix = new Matrix();
matrix.postScale(scale, 1, getWidth() / 2, getHeight() / 2);
setTransform(matrix);
}
/**
* 视频宽度适配
* @param width
* @param height
*/
public void setVideoAspectRatio(int width, int height)
{
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
float mRatio = (float) mRatioWidth / (float) mRatioHeight; //算出相机的缩放比例
if(mRatio < 1.0)
{
setAspectRatio(width, height);
}else {
float h = getWidth() / mRatio;
float scale;
if (h > getHeight())
scale = (float) getHeight() / h;
else
scale = h / (float) getHeight();
Matrix matrix = new Matrix();
matrix.postScale(1, scale, getWidth() / 2, getHeight() / 2);
setTransform(matrix);
}
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/AutoLocateHorizontalView.java
================================================
package camera.cn.cameramaster.view;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Scroller;
/**
* 横向recyclerView
*
* @author ymc
*/
public class AutoLocateHorizontalView extends RecyclerView {
/**
* 一个屏幕中显示多少个item,必须为奇数
*/
private int itemCount = 5;
/**
* 初始时选中的位置
*/
private int initPos = 0;
private int deltaX;
private WrapperAdapter wrapAdapter;
private Adapter adapter;
private LinearLayoutManager linearLayoutManager;
private boolean isInit;
private OnSelectedPositionChangedListener listener;
/**
* 刚初始化时是否触发位置改变的监听
*/
private boolean isFirstPosChanged = true;
/**
* 记录上次选中的位置
*/
private int oldSelectedPos = initPos;
/**
* 当前被选中的位置
*/
private int selectPos = initPos;
private Scroller mScroller;
/**
* 当要调用moveToPosition()方法时要先记录已经移动了多少位置
*/
private int oldMoveX;
private boolean isMoveFinished = true;
public AutoLocateHorizontalView(Context context) {
super(context);
}
public AutoLocateHorizontalView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public AutoLocateHorizontalView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private void init() {
mScroller = new Scroller(getContext());
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (isInit) {
if (initPos >= adapter.getItemCount()) {
initPos = adapter.getItemCount() - 1;
}
if (isFirstPosChanged && listener != null) {
listener.selectedPositionChanged(initPos);
}
linearLayoutManager.scrollToPositionWithOffset(0,
-initPos * (wrapAdapter.getItemWidth()));
isInit = false;
}
}
});
}
/**
* 设置初始化时选中的位置,该方法必须在
* {@link AutoLocateHorizontalView#setAdapter(android.support.v7.widget.RecyclerView.Adapter) }
* 之前调用
*
* @param initPos 初始位置,如果位置超过了item的数量则默认选中最后一项item
*/
public void setInitPos(int initPos) {
if (adapter != null) {
throw new RuntimeException("This method should be called before setAdapter()!");
}
this.initPos = initPos;
selectPos = initPos;
oldSelectedPos = initPos;
}
/**
* 设置每次显示多少个item,该方法必须在{@link AutoLocateHorizontalView#setAdapter(android.support.v7.widget.RecyclerView.Adapter) }之前调用
*
* @param itemCount 必须为奇数,否则默认会设置成小于它的最大奇数
*/
public void setItemCount(int itemCount) {
if (adapter != null) {
throw new RuntimeException("This method should be called before setAdapter()!");
}
if (itemCount % 2 == 0) {
this.itemCount = itemCount - 1;
} else {
this.itemCount = itemCount;
}
}
/**
* 删除item后偏移距离可能需要重新计算,从而保证selectPos的正确
*
* @param adapter
*/
private void correctDeltax(Adapter adapter) {
if (adapter.getItemCount() <= selectPos) {
deltaX -= wrapAdapter.getItemWidth() * (selectPos - adapter.getItemCount() + 1);
}
calculateSelectedPos();
}
/**
* 删除时选中的数据发生改变,要重新回调方法
*
* @param startPos
*/
private void reCallListenerWhenRemove(int startPos) {
if (startPos <= selectPos && listener != null) {
correctDeltax(adapter);
listener.selectedPositionChanged(selectPos);
} else {
correctDeltax(adapter);
}
}
/**
* 添加数据时选中的数据发生改变,要重新回调方法
*
* @param startPos
*/
private void reCallListenerWhenAdd(int startPos) {
if (startPos <= selectPos && listener != null) {
listener.selectedPositionChanged(selectPos);
}
}
/**
* 当使用整体刷新时要重新回调方法
*/
private void reCallListenerWhenChanged() {
if (listener != null) {
listener.selectedPositionChanged(selectPos);
}
}
@Override
public void setAdapter(final Adapter adapter) {
this.adapter = adapter;
this.wrapAdapter = new WrapperAdapter(adapter, getContext(), itemCount);
adapter.registerAdapterDataObserver(new AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
wrapAdapter.notifyDataSetChanged();
reCallListenerWhenChanged();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
wrapAdapter.notifyDataSetChanged();
reCallListenerWhenAdd(positionStart);
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
wrapAdapter.notifyDataSetChanged();
reCallListenerWhenRemove(positionStart);
}
});
deltaX = 0;
if (linearLayoutManager == null) {
linearLayoutManager = new LinearLayoutManager(getContext());
}
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
super.setLayoutManager(linearLayoutManager);
super.setAdapter(this.wrapAdapter);
isInit = true;
}
@Override
public void setLayoutManager(LayoutManager layout) {
if (!(layout instanceof LinearLayoutManager)) {
throw new IllegalStateException("The LayoutManager here must be LinearLayoutManager!");
}
this.linearLayoutManager = (LinearLayoutManager) layout;
}
@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
if (state == SCROLL_STATE_IDLE) {
if (wrapAdapter == null) {
return;
}
int itemWidth = wrapAdapter.getItemWidth();
int headerFooterWidth = wrapAdapter.getHeaderFooterWidth();
if (itemWidth == 0 || headerFooterWidth == 0) {
//此时adapter还没有准备好,忽略此次调用
return;
}
//超出上个item的位置
int overLastPosOffset = deltaX % itemWidth;
if (overLastPosOffset == 0) {
//刚好处于一个item选中位置,无需滑动偏移纠正
} else if (Math.abs(overLastPosOffset) <= itemWidth / 2) {
scrollBy(-overLastPosOffset, 0);
} else if (overLastPosOffset > 0) {
scrollBy((itemWidth - overLastPosOffset), 0);
} else {
scrollBy(-(itemWidth + overLastPosOffset), 0);
}
calculateSelectedPos();
//此处通知刷新是为了重新绘制之前被选中的位置以及刚刚被选中的位置
wrapAdapter.notifyItemChanged(oldSelectedPos + 1);
wrapAdapter.notifyItemChanged(selectPos + 1);
oldSelectedPos = selectPos;
if (listener != null) {
listener.selectedPositionChanged(selectPos);
}
}
}
public void moveToPosition(int position) {
if(position < 0 || position > adapter.getItemCount() - 1){
throw new IllegalArgumentException("Your position should be from 0 to "+(adapter.getItemCount()-1));
}
oldMoveX = 0;
isMoveFinished = false;
int itemWidth = wrapAdapter.getItemWidth();
if (position != selectPos) {
int deltx = (position - selectPos) * itemWidth;
mScroller.startScroll(getScrollX(), getScrollY(), deltx, 0);
postInvalidate();
}
}
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) {
int x = mScroller.getCurrX() - oldMoveX;
oldMoveX += x;
scrollBy(x, 0);
} else if (mScroller.isFinished()) {
//此处通知刷新是为了重新绘制之前被选中的位置以及刚刚被选中的位置
if (isMoveFinished) {
return;
}
wrapAdapter.notifyItemChanged(oldSelectedPos + 1);
wrapAdapter.notifyItemChanged(selectPos + 1);
oldSelectedPos = selectPos;
if (listener != null) {
listener.selectedPositionChanged(selectPos);
}
isMoveFinished = true;
}
}
@Override
public void onScrolled(int dx, int dy) {
super.onScrolled(dx, dy);
deltaX += dx;
calculateSelectedPos();
}
private void calculateSelectedPos() {
int itemWidth = wrapAdapter.getItemWidth();
if (deltaX > 0) {
selectPos = (deltaX) / itemWidth + initPos;
} else {
selectPos = initPos + (deltaX) / itemWidth;
}
}
class WrapperAdapter extends RecyclerView.Adapter {
private Context context;
private RecyclerView.Adapter adapter;
private int itemCount;
private static final int HEADER_FOOTER_TYPE = -1;
private View itemView;
/**
* 头部或尾部的宽度
*/
private int headerFooterWidth;
/**
* 每个item的宽度
*/
private int itemWidth;
public WrapperAdapter(Adapter adapter, Context context, int itemCount) {
this.adapter = adapter;
this.context = context;
this.itemCount = itemCount;
if (adapter instanceof IAutoLocateHorizontalView) {
itemView = ((IAutoLocateHorizontalView) adapter).getItemView();
} else {
throw new RuntimeException(adapter.getClass().getSimpleName() + " should implements com.jianglei.view.AutoLocateHorizontalView.IAutoLocateHorizontalView !");
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == HEADER_FOOTER_TYPE) {
View view = new View(context);
headerFooterWidth = parent.getMeasuredWidth() / 2 - (parent.getMeasuredWidth() / itemCount) / 2;
RecyclerView.LayoutParams params = new LayoutParams(headerFooterWidth, ViewGroup.LayoutParams.MATCH_PARENT);
view.setLayoutParams(params);
return new HeaderFooterViewHolder(view);
}
ViewHolder holder = adapter.onCreateViewHolder(parent, viewType);
itemView = ((IAutoLocateHorizontalView) adapter).getItemView();
int width = parent.getMeasuredWidth() / itemCount;
ViewGroup.LayoutParams params = itemView.getLayoutParams();
if (params != null) {
params.width = width;
itemWidth = width;
itemView.setLayoutParams(params);
}
return holder;
}
@SuppressWarnings("unchecked")
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (!isHeaderOrFooter(position)) {
adapter.onBindViewHolder(holder, position - 1);
if (selectPos == position - 1) {
((IAutoLocateHorizontalView) adapter).onViewSelected(true, position - 1, holder, itemWidth);
} else {
((IAutoLocateHorizontalView) adapter).onViewSelected(false, position - 1, holder, itemWidth);
}
}
}
@Override
public int getItemCount() {
return adapter.getItemCount() + 2;
}
@Override
public int getItemViewType(int position) {
if (position == 0 || position == getItemCount() - 1) {
return HEADER_FOOTER_TYPE;
}
return adapter.getItemViewType(position - 1);
}
private boolean isHeaderOrFooter(int pos) {
if (pos == 0 || pos == getItemCount() - 1) {
return true;
}
return false;
}
public int getHeaderFooterWidth() {
return headerFooterWidth;
}
public int getItemWidth() {
return itemWidth;
}
class HeaderFooterViewHolder extends RecyclerView.ViewHolder {
HeaderFooterViewHolder(View itemView) {
super(itemView);
}
}
}
public interface IAutoLocateHorizontalView {
/**
* 获取item的根布局
*/
View getItemView();
/**
* 当item被选中时会触发这个回调,可以修改被选中时的样式
*
* @param isSelected 是否被选中
* @param pos 当前view的位置
* @param holder
* @param itemWidth 当前整个item的宽度
*/
void onViewSelected(boolean isSelected, int pos, ViewHolder holder, int itemWidth);
}
/***
* 选中位置改变时的监听
*/
public interface OnSelectedPositionChangedListener {
void selectedPositionChanged(int pos);
}
public void setOnSelectedPositionChangedListener(OnSelectedPositionChangedListener listener) {
this.listener = listener;
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/AutoTextureView.java
================================================
package camera.cn.cameramaster.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;
/**
* 自定义 正方形预览界面
*
* @packageName: camera.cn.cameramaster.view
* @fileName: AutoTextureView
* @date: 2019/5/9 16:15
* @author: ymc
* @QQ:745612618
*/
public class AutoTextureView extends TextureView {
private int mRatioWidth = 0;
private int mRatioHeight = 0;
public AutoTextureView(Context context) {
super(context);
}
public AutoTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
* is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
*
* @param width Relative horizontal size
* @param height Relative vertical size
*/
public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth / mRatioHeight) {
setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
} else {
setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
}
}
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/AwbSeekBar.java
================================================
package camera.cn.cameramaster.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.widget.SeekBar;
/**
* 自定义 8种白平衡状态 选择 seekBar
*
* @author ymc
*/
@SuppressLint("AppCompatCustomView")
public class AwbSeekBar extends SeekBar {
private int mProgress;
private AwbSeekBar mAwbSeekBar = this;
private OnAwbSeekBarChangeListener mOnAwbSeekBarChangeListener;
public AwbSeekBar(Context context) {
super(context);
init();
}
public AwbSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AwbSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public AwbSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public void setmOnAwbSeekBarChangeListener(OnAwbSeekBarChangeListener mOnAwbSeekBarChangeListener) {
this.mOnAwbSeekBarChangeListener = mOnAwbSeekBarChangeListener;
}
private void init() {
this.setMax(70);
this.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mProgress = progress;
if (mOnAwbSeekBarChangeListener != null) {
if (0 <= mProgress && mProgress < 5) {
mOnAwbSeekBarChangeListener.doInProgress1();
} else if (5 <= mProgress && mProgress < 15) {
mOnAwbSeekBarChangeListener.doInProgress2();
} else if (15 <= mProgress && mProgress < 25) {
mOnAwbSeekBarChangeListener.doInProgress3();
} else if (25 <= mProgress && mProgress < 35) {
mOnAwbSeekBarChangeListener.doInProgress4();
} else if (35 <= mProgress && mProgress < 45) {
mOnAwbSeekBarChangeListener.doInProgress5();
} else if (45 <= mProgress && mProgress < 55) {
mOnAwbSeekBarChangeListener.doInProgress6();
} else if (55 <= mProgress && mProgress < 65) {
mOnAwbSeekBarChangeListener.doInProgress7();
} else if (65 <= mProgress && mProgress < 70) {
mOnAwbSeekBarChangeListener.doInProgress8();
}
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
mOnAwbSeekBarChangeListener.onStartTrackingTouch(seekBar);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int num = 0;
if (0 <= mProgress && mProgress < 5) {
mAwbSeekBar.setProgress(0);
num = 0;
} else if (5 <= mProgress && mProgress < 15) {
mAwbSeekBar.setProgress(10);
num = 10;
} else if (15 <= mProgress && mProgress < 25) {
mAwbSeekBar.setProgress(20);
num = 20;
} else if (25 <= mProgress && mProgress < 35) {
mAwbSeekBar.setProgress(30);
num = 30;
} else if (35 <= mProgress && mProgress < 45) {
mAwbSeekBar.setProgress(40);
num = 40;
} else if (45 <= mProgress && mProgress < 55) {
mAwbSeekBar.setProgress(50);
num = 50;
} else if (55 <= mProgress && mProgress < 65) {
mAwbSeekBar.setProgress(60);
num = 60;
} else if (65 <= mProgress && mProgress < 70) {
mAwbSeekBar.setProgress(70);
num = 70;
}
if (mOnAwbSeekBarChangeListener != null) {
mOnAwbSeekBarChangeListener.onStopTrackingTouch(num);
}
}
});
}
public interface OnAwbSeekBarChangeListener {
public abstract void doInProgress1();
public abstract void doInProgress2();
public abstract void doInProgress3();
public abstract void doInProgress4();
public abstract void doInProgress5();
public abstract void doInProgress6();
public abstract void doInProgress7();
public abstract void doInProgress8();
public abstract void onStopTrackingTouch(int num);
public abstract void onStartTrackingTouch(SeekBar seekBar);
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/AwbSeekBarChangeListener.java
================================================
package camera.cn.cameramaster.view;
import android.content.Context;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.SeekBar;
import android.widget.TextView;
import camera.cn.cameramaster.R;
import camera.cn.cameramaster.view.AwbSeekBar;
/**
* 自定义 seekbar 滑动监听事件
* @author ymc
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class AwbSeekBarChangeListener implements AwbSeekBar.OnAwbSeekBarChangeListener {
private TextView mTextView;
private CaptureRequest.Builder mPreviewBuilder;
private CameraCaptureSession mCameraCaptureSession;
private Handler mHandler;
private CameraCaptureSession.CaptureCallback mPreviewSessionCallback;
private Animation mAlphaInAnimation;
private Animation mAlphaOutAnimation;
public AwbSeekBarChangeListener(Context mContext, TextView mTextView, CaptureRequest.Builder mPreviewBuilder,
CameraCaptureSession mCameraCaptureSession, Handler mHandler,
CameraCaptureSession.CaptureCallback mPreviewSessionCallback) {
this.mTextView = mTextView;
this.mPreviewBuilder = mPreviewBuilder;
this.mCameraCaptureSession = mCameraCaptureSession;
this.mHandler = mHandler;
this.mPreviewSessionCallback = mPreviewSessionCallback;
mAlphaInAnimation = AnimationUtils.loadAnimation(mContext, R.anim.alpha_in);
mAlphaOutAnimation = AnimationUtils.loadAnimation(mContext, R.anim.alpha_out);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void doInProgress1() {
mTextView.setText("自动");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
updatePreview();
}
@Override
public void doInProgress2() {
mTextView.setText("多云");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
updatePreview();
}
@Override
public void doInProgress3() {
mTextView.setText("白天");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_DAYLIGHT);
updatePreview();
}
@Override
public void doInProgress4() {
mTextView.setText("日光灯");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_FLUORESCENT);
updatePreview();
}
@Override
public void doInProgress5() {
mTextView.setText("白炽灯");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_INCANDESCENT);
updatePreview();
}
@Override
public void doInProgress6() {
mTextView.setText("阴影");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_SHADE);
updatePreview();
}
@Override
public void doInProgress7() {
mTextView.setText("黄昏");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_TWILIGHT);
updatePreview();
}
@Override
public void doInProgress8() {
mTextView.setText("暖光");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_WARM_FLUORESCENT);
updatePreview();
}
@Override
public void onStopTrackingTouch(int num) {
switch (num) {
case 0:
mTextView.setText("自动");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
break;
case 10:
mTextView.setText("多云");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
break;
case 20:
mTextView.setText("白天");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_DAYLIGHT);
break;
case 30:
mTextView.setText("日光灯");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_FLUORESCENT);
break;
case 40:
mTextView.setText("白炽灯");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_INCANDESCENT);
break;
case 50:
mTextView.setText("阴影");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_SHADE);
break;
case 60:
mTextView.setText("黄昏");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_TWILIGHT);
break;
case 70:
mTextView.setText("暖光");
mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_WARM_FLUORESCENT);
break;
}
updatePreview();
mTextView.startAnimation(mAlphaOutAnimation);
mTextView.setVisibility(View.INVISIBLE);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
mTextView.setVisibility(View.VISIBLE);
mTextView.startAnimation(mAlphaInAnimation);
}
/**
* 更新预览
*/
private void updatePreview() {
try {
mCameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), mPreviewSessionCallback, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
Log.i("updatePreview", "ExceptionExceptionException");
}
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/CameraV2GLSurfaceView.java
================================================
package camera.cn.cameramaster.view;
import android.content.Context;
import android.opengl.GLSurfaceView;
import camera.cn.cameramaster.util.render.CameraV2Renderer;
import camera.cn.cameramaster.util.CameraV2;
/**
* CameraV2 GLSurfaceView
* 参考url : [https://blog.csdn.net/lb377463323/article/details/78054892]
*
* @date 2019年2月12日 13:41:16
* @author ymc
*/
public class CameraV2GLSurfaceView extends GLSurfaceView {
public static boolean shouldTakePic = false;
public void init(CameraV2 camera, boolean isPreviewStarted, Context context) {
setEGLContextClientVersion(2);
CameraV2Renderer mCameraV2Renderer = new CameraV2Renderer();
mCameraV2Renderer.init(this, camera, isPreviewStarted, context);
setRenderer(mCameraV2Renderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
public CameraV2GLSurfaceView(Context context) {
super(context);
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/ShowSurfaceView.java
================================================
package camera.cn.cameramaster.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* @packageName: cn.tongue.tonguecamera.view
* @fileName: ShowSurfaceView
* @date: 2019/3/7 13:17
* @author: ymc
* @QQ:745612618
*/
public class ShowSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private SurfaceHolder mSurfaceHolder;
/**
* 绘图的Canvas
*/
private Canvas mCanvas;
/**
* 子线程标志位
*/
private boolean mIsDrawing;
private Bitmap bitmap;
private Paint mPaint;
public ShowSurfaceView(Context context) {
this(context, null);
}
public ShowSurfaceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ShowSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
setFocusable(true);
setKeepScreenOn(true);
setFocusableInTouchMode(true);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(5);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
//开启子线程
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//改变
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}
@Override
public void run() {
while (mIsDrawing) {
drawSomething();
}
}
//绘图逻辑
private void drawSomething() {
try {
//获得canvas对象
mCanvas = mSurfaceHolder.lockCanvas();
// Bitmap bitmap1= BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
if (bitmap != null) {
mCanvas.drawBitmap(bitmap, 0, 0, mPaint);
}
//绘图
} catch (Exception e) {
} finally {
if (mCanvas != null) {
//释放canvas对象并提交画布
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
}
================================================
FILE: app/src/main/java/camera/cn/cameramaster/view/SleepThread.java
================================================
package camera.cn.cameramaster.view;
import android.os.Handler;
import android.os.Message;
/**
* 睡眠线程
*
* @author ymc
*/
public class SleepThread implements Runnable {
private Handler mMainHandler;
private int what;
private long mTime;
private Object mObject;
public SleepThread(Handler mainHandler, int what, long mTime, Object mObject) {
this.mMainHandler = mainHandler;
this.what = what;
this.mTime = mTime;
this.mObject = mObject;
}
@Override
public void run() {
try {
Thread.sleep(mTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = mMainHandler.obtainMessage();
message.what = what;
message.obj = mObject;
mMainHandler.sendMessage(message);
}
}
================================================
FILE: app/src/main/res/anim/alpha_in.xml
================================================