package com.eighteengray.procamera.fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.camera2.CameraAccessException;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.eighteengray.commonutillibrary.FileUtils;
import com.eighteengray.commonutillibrary.ImageUtils;
import com.eighteengray.procamera.R;
import com.eighteengray.procamera.activity.AlbumActivity;
import com.eighteengray.procamera.activity.SettingActivity;
import com.eighteengray.procamera.business.ImageSaver;
import com.eighteengray.procamera.widget.TextureViewTouchListener;
import com.eighteengray.procamera.widget.VerticalSeekBar;
import com.eighteengray.procamera.widget.baserecycler.BaseRecyclerAdapter;
import com.eighteengray.procamera.widget.baserecycler.BaseRecyclerViewHolder;
import com.eighteengray.procamera.widget.dialogfragment.ModeSelectDialogFragment;
import com.eighteengray.procamera.widget.dialogfragment.PopupWindowFactory;
import com.eighteengray.procameralibrary.camera.Camera2TextureView;
import com.eighteengray.procameralibrary.common.Constants;
import com.eighteengray.procameralibrary.dataevent.CameraConfigure;
import com.eighteengray.procameralibrary.dataevent.ImageAvailableEvent;
import com.eighteengray.procameralibrary.camera.TextureViewTouchEvent;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.File;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import static com.eighteengray.commonutillibrary.SDCardUtils.getSystemPicFile;
/**
* 待完成功能:
* 1.拍照相关:拍摄比例调节,九宫格,连拍,延时拍摄,手动调节焦距,对焦点和测光点分离,gpu滤镜,
* 图片数字签名(位置、时间、版权),水平校准。
* 2.处理相关:参考snapseed、vsco、prisma、拼图。
*/
public class Camera2Fragment extends BaseCameraFragment
{
View view;
//上部
@BindView(R.id.iv_flash_camera)
ImageView iv_flash_camera;
@BindView(R.id.tv_mode_gpufileter)
TextView tv_mode_gpufileter;
@BindView(R.id.iv_switch_camera)
ImageView iv_switch_camera;
//拍照
@BindView(R.id.cameraTextureView)
Camera2TextureView cameraTextureView;
@BindView(R.id.iv_imageavailable)
ImageView iv_imageavailable;
@BindView(R.id.seekbar_camera2)
VerticalSeekBar seekbar_camera2;
@BindView(R.id.iv_focus_camera)
ImageView iv_focus_camera;
//Scene和Effect的RecyclerView
@BindView(R.id.rcv_scene)
RecyclerView rcv_scene;
BaseRecyclerAdapter<String> sceneRecyclerAdapter;
ArrayList<String> sceneArrayList = new ArrayList<>();
@BindView(R.id.rcv_effect)
RecyclerView rcv_effect;
BaseRecyclerAdapter<String> effectRecyclerAdapter;
ArrayList<String> effectArrayList = new ArrayList<>();
//中下部
@BindView(R.id.rl_middle_bottom_menu)
RelativeLayout rl_middle_bottom_menu;
@BindView(R.id.iv_hdr_camera)
ImageView iv_hdr_camera;
@BindView(R.id.tv_mode_select)
TextView tv_mode_select;
@BindView(R.id.iv_gpufilter_camera)
ImageView iv_gpufilter_camera;
//下部
@BindView(R.id.rl_bottommenu)
RelativeLayout rl_bottommenu;
@BindView(R.id.iv_album_camera)
ImageView iv_album_camera;
@BindView(R.id.iv_ratio_camera)
ImageView iv_ratio_camera;
@BindView(R.id.iv_shutter_camera)
ImageView iv_shutter_camera;
@BindView(R.id.iv_delay_shutter)
ImageView iv_delay_shutter;
@BindView(R.id.tv_delay_second)
TextView tv_delay_second;
@BindView(R.id.iv_setting_camera)
ImageView iv_setting_camera;
Handler handler; //用来更新UI的handler
private boolean mFlagShowFocusImage = false; //聚焦图像是否显示的标志位
private float mRawX, mRawY; //触摸聚焦时候的中心点
protected File mFile; //保存图片的路径
private int delayTime = 0;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_camera2, container, false);
ButterKnife.bind(this, view);
EventBus.getDefault().register(this);
handler = new Handler(Looper.getMainLooper());
mFile = FileUtils.createSaveBitmapFile(getActivity());
return view;
}
@Override
public void onResume()
{
super.onResume();
cameraTextureView.openCamera();
cameraTextureView.setOnTouchListener(new TextureViewTouchListener());
initView();
}
private void initView()
{
LinearLayoutManager sceneLayoutManager = new LinearLayoutManager(getActivity());
sceneLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
rcv_scene.setLayoutManager(sceneLayoutManager);
sceneRecyclerAdapter = new BaseRecyclerAdapter<String>(R.layout.item_text_grid)
{
@Override
public void setData2ViewR(BaseRecyclerViewHolder baseRecyclerViewHolder, final String item, int position)
{
TextView textView = baseRecyclerViewHolder.getViewById(R.id.tv_item_textgrid);
textView.setText(item);
textView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
CameraConfigure.Scene scene = new CameraConfigure.Scene();
scene.setScene(item);
EventBus.getDefault().post(scene);
rcv_scene.setVisibility(View.GONE);
}
});
}
};
rcv_scene.setAdapter(sceneRecyclerAdapter);
setSceneData();
sceneRecyclerAdapter.setData(sceneArrayList);
LinearLayoutManager effectLayoutManager = new LinearLayoutManager(getActivity());
effectLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
rcv_effect.setLayoutManager(effectLayoutManager);
effectRecyclerAdapter = new BaseRecyclerAdapter<String>(R.layout.item_text_grid)
{
@Override
public void setData2ViewR(BaseRecyclerViewHolder baseRecyclerViewHolder, final String item, int position)
{
TextView textView = baseRecyclerViewHolder.getViewById(R.id.tv_item_textgrid);
textView.setText(item);
textView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
CameraConfigure.Effect effect = new CameraConfigure.Effect();
effect.setEffect(item);
EventBus.getDefault().post(effect);
rcv_effect.setVisibility(View.GONE);
}
});
}
};
rcv_effect.setAdapter(effectRecyclerAdapter);
setEffectData();
effectRecyclerAdapter.setData(effectArrayList);
seekbar_camera2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
try
{
cameraTextureView.changeFocusDistance(progress);
} catch (CameraAccessException e)
{
e.printStackTrace();
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
});
}
@Override
public void onPause()
{
if(cameraTextureView != null)
{
cameraTextureView.closeCamera();
}
super.onPause();
}
@Override
public void onDestroy()
{
EventBus.getDefault().unregister(this);
super.onDestroy();
}
@OnClick({R.id.iv_flash_camera, R.id.iv_switch_camera,
R.id.iv_hdr_camera, R.id.tv_mode_select, R.id.iv_gpufilter_camera,
R.id.iv_album_camera, R.id.iv_ratio_camera, R.id.iv_shutter_camera, R.id.iv_delay_shutter, R.id.iv_setting_camera})
public void click(View view)
{
switch (view.getId())
{
case R.id.iv_flash_camera: //闪光灯
tv_mode_gpufileter.setVisibility(View.GONE);
int[] location1 = new int[2];
iv_flash_camera.getLocationOnScreen(location1);
PopupWindowFactory.createFlashPopupWindow(getActivity()).showAtLocation(iv_flash_camera, Gravity.NO_GRAVITY, location1[0]+iv_flash_camera.getWidth(), location1[1]-iv_flash_camera.getHeight());
break;
case R.id.iv_switch_camera: //切换摄像头
cameraTextureView.switchCamera();
break;
case R.id.iv_hdr_camera: //hdr设置
rcv_scene.setVisibility(View.VISIBLE);
break;
case R.id.tv_mode_select: //模式选择,相机、视频
ModeSelectDialogFragment modeSelectDialogFragment = new ModeSelectDialogFragment();
modeSelectDialogFragment.show(getFragmentManager(), "mode");
break;
case R.id.iv_gpufilter_camera: //添加gpu滤镜
rcv_effect.setVisibility(View.VISIBLE);
break;
case R.id.iv_album_camera: //进入相册
Intent intent_album = new Intent(getActivity(), AlbumActivity.class);
startActivity(intent_album);
break;
case R.id.iv_ratio_camera: //弹出比例修改对话框,修改拍摄比例
int[] location3 = new int[2];
iv_ratio_camera.getLocationOnScreen(location3);
PopupWindowFactory.createRatioPopupWindow(getActivity()).showAtLocation(iv_ratio_camera, Gravity.BOTTOM, 0, rl_bottommenu.getHeight() + rl_middle_bottom_menu.getHeight());
break;
case R.id.iv_shutter_camera: //点击拍摄,执行拍摄操作(要结合已经点击的配置),存储图像,然后把图像显示到屏幕上。
// 然后图片通过动画下到相册按钮,相册按钮显示图片缩略图,然后主屏幕进入预览
cameraTextureView.takePicture();
break;
case R.id.iv_delay_shutter: //在延时TextView上显示时间(做放大缩小动画),同时执行延时拍摄配置
switch (delayTime)
{
case 0:
delayTime = 3;
break;
case 3:
delayTime = 10;
break;
case 10:
delayTime = 0;
break;
}
tv_delay_second.setText(delayTime + "");
cameraTextureView.setDalayTime(delayTime * 1000);
break;
case R.id.iv_setting_camera: //进入设置界面
Intent intent_setting = new Intent(getActivity(), SettingActivity.class);
startActivity(intent_setting);
break;
}
}
private void setSceneData()
{
sceneArrayList.add("DISABLED");
sceneArrayList.add("FACE_PRIORITY");
sceneArrayList.add("ACTION");
sceneArrayList.add("PORTRAIT");
sceneArrayList.add("LANDSCAPE");
sceneArrayList.add("NIGHT");
sceneArrayList.add("PORTRAIT");
sceneArrayList.add("THEATRE");
sceneArrayList.add("BEACH");
sceneArrayList.add("SNOW");
sceneArrayList.add("SUNSET");
sceneArrayList.add("STEADYPHOTO");
sceneArrayList.add("FIREWORKS");
sceneArrayList.add("SPORTS");
sceneArrayList.add("PARTY");
sceneArrayList.add("CANDLELIGHT");
sceneArrayList.add("BARCODE");
sceneRecyclerAdapter.setData(sceneArrayList);
}
private void setEffectData()
{
effectArrayList.add("AQUA");
effectArrayList.add("BLACKBOARD");
effectArrayList.add("MONO");
effectArrayList.add("NEGATIVE");
effectArrayList.add("POSTERIZE");
effectArrayList.add("SEPIA");
effectArrayList.add("SOLARIZE");
effectArrayList.add("WHITEBOARD");
effectArrayList.add("OFF");
effectRecyclerAdapter.setData(effectArrayList);
}
//EventBus--TextureView触摸事件
@Subscribe(threadMode = ThreadMode.MAIN) //轻按:显示焦点,完成聚焦和测光。
public void onTextureClick(TextureViewTouchEvent.TextureClick textureClick) throws CameraAccessException
{
mRawX = textureClick.getRawX();
mRawY = textureClick.getRawY();
cameraTextureView.focusRegion(textureClick.getX(), textureClick.getY());
}
@Subscribe(threadMode = ThreadMode.MAIN) //长按:进行测光点和对焦点锁定
public void onTextureLongClick(TextureViewTouchEvent.TextureLongClick textureLongClick)
{
Toast.makeText(getActivity(), "longclick", Toast.LENGTH_SHORT).show();
}
@Subscribe(threadMode = ThreadMode.MAIN) // 单指滑动,如果是向右下则进度环增加,否则减小,用于调节焦点白平衡。
public void onTextureOneDrag(TextureViewTouchEvent.TextureOneDrag textureOneDrag)
{
Toast.makeText(getActivity(), "onedrag", Toast.LENGTH_SHORT).show();
}
//针对上面的聚焦,这四个是聚焦成功、失败等状态时显示的view
@Subscribe(threadMode = ThreadMode.MAIN)
public void onShowFocus(TextureViewTouchEvent.FocusState focusState)
{
switch (focusState.getFocusState())
{
case Constants.FOCUS_FOCUSING:
if (mFlagShowFocusImage == false)
{
//聚焦图片显示在手点击的位置
if(mRawX == 0 || mRawY == 0)
{
mRawX = cameraTextureView.getMeasuredWidth() / 2 - 100;
mRawY = cameraTextureView.getMeasuredHeight() / 2;
}
int width = iv_focus_camera.getWidth();
int height = iv_focus_camera.getHeight();
ViewGroup.MarginLayoutParams margin = new ViewGroup.MarginLayoutParams(iv_focus_camera.getLayoutParams());
margin.setMargins((int)(mRawX - width / 2), (int)(mRawY - height / 2), margin.rightMargin, margin.bottomMargin);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(margin);
iv_focus_camera.setLayoutParams(layoutParams);
iv_focus_camera.setVisibility(View.VISIBLE);
iv_focus_camera.setImageResource(R.mipmap.focusing);
ScaleAnimation scaleAnimation = new ScaleAnimation(2.0f, 1.0f, 2.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(200);
iv_focus_camera.startAnimation(scaleAnimation);
handler.postDelayed(new Runnable()
{
@Override
public void run()
{
iv_focus_camera.setVisibility(View.GONE);
}
}, 1000);
mFlagShowFocusImage = true;
}
break;
case Constants.FOCUS_SUCCEED:
if (mFlagShowFocusImage == true)
{
iv_focus_camera.setVisibility(View.VISIBLE);
iv_focus_camera.setImageResource(R.mipmap.focus_succeed);
handler.postDelayed(new Runnable()
{
@Override
public void run()
{
iv_focus_camera.setVisibility(View.GONE);
}
}, 1000);
mFlagShowFocusImage = false;
}
break;
case Constants.FOCUS_INACTIVE:
iv_focus_camera.setVisibility(View.GONE);
mFlagShowFocusImage = false;
break;
case Constants.FOCUS_FAILED:
if (mFlagShowFocusImage == true)
{
iv_focus_camera.setVisibility(View.VISIBLE);
iv_focus_camera.setImageResource(R.mipmap.focus_failed);
handler.postDelayed(new Runnable()
{
@Override
public void run()
{
iv_focus_camera.setVisibility(View.GONE);
}
}, 1000);
mFlagShowFocusImage = false;
}
break;
}
}
//EventBus--接收相机配置的参数
@Subscribe(threadMode = ThreadMode.MAIN)
public void onFlashSelect(CameraConfigure.Flash flash) throws CameraAccessException
{
tv_mode_gpufileter.setVisibility(View.VISIBLE);
switch (flash.getFlash())
{
case Constants.FLASH_AUTO:
iv_flash_camera.setImageResource(R.mipmap.flash_auto_white_24dp);
break;
case Constants.FLASH_ON:
iv_flash_camera.setImageResource(R.mipmap.flash_on_white_24dp);
break;
case Constants.FLASH_OFF:
iv_flash_camera.setImageResource(R.mipmap.flash_off_white_24dp);
break;
case Constants.FLASH_FLARE:
iv_flash_camera.setImageResource(R.mipmap.flash_flare_white_24dp);
break;
}
cameraTextureView.setFlashMode(flash.getFlash());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSceneSelect(CameraConfigure.Scene scene) throws CameraAccessException
{
cameraTextureView.setSceneMode(scene.getScene());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEffectSelect(CameraConfigure.Effect effect) throws CameraAccessException
{
tv_mode_gpufileter.setText(effect.getEffect());
cameraTextureView.setEffectMode(effect.getEffect());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onRatioSelect(CameraConfigure.Ratio ratio)
{
cameraTextureView.setRatioMode(ratio.getRatio());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDelayTime(CameraConfigure.DelayTime delayTime)
{
switch (delayTime.getDelaytime())
{
case Constants.DELAY_3:
break;
case Constants.DELAY_5:
break;
case Constants.DELAY_8:
break;
case Constants.DELAY_10:
break;
}
}
//拍照完成后,拿到ImageReader做响应操作
@Subscribe(threadMode = ThreadMode.MAIN)
public void onImageReaderAvailable(ImageAvailableEvent.ImageReaderAvailable imageReaderAvailable)
{
new Thread(new ImageSaver(imageReaderAvailable.getImageReader(), mFile)).start();
}
//拍照完成后,拿到ImagePath显示图片,延时隐藏图片
@Subscribe(threadMode = ThreadMode.MAIN)
public void onImagePathAvailable(ImageAvailableEvent.ImagePathAvailable imagePathAvailable)
{
Bitmap bitmap = ImageUtils.getBitmapFromPath(imagePathAvailable.getImagePath());
final Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, 60, 60);
iv_imageavailable.setImageResource(R.color.black_deep);
iv_imageavailable.setVisibility(View.VISIBLE);
handler.postDelayed(new Runnable()
{
@Override
public void run()
{
iv_imageavailable.setVisibility(View.GONE);
iv_album_camera.setImageBitmap(thumbnail);
}
}, 200);
}
}