助けてください。カメラAPI(Android SDK 19と17の間のバージョン)を使用して、カメラを長時間押すとシャッターボタンを押す前にピントを合わせる方法はありますか?シャッターボタンの長押しでAndroidフォーカスカメラ
つまり、私はカメラのボタンを長押しします(これはカメラのボタンまたは画面上のボタンになる可能性があることを意味します)。フォーカスは開始しなければなりません。画像。
助けてください。
助けてください。カメラAPI(Android SDK 19と17の間のバージョン)を使用して、カメラを長時間押すとシャッターボタンを押す前にピントを合わせる方法はありますか?シャッターボタンの長押しでAndroidフォーカスカメラ
つまり、私はカメラのボタンを長押しします(これはカメラのボタンまたは画面上のボタンになる可能性があることを意味します)。フォーカスは開始しなければなりません。画像。
助けてください。
この機能では、onTouchEvent(リリースボタンを検出できる場所)とsetOnLongClickListener(写真を撮る長押しボタンを検出する)の2つのメソッドがあります。下のコードでは、SurfaceViewの上のスクリーンに赤い円を描画するカスタムビュー(DrawCameraOptionsクラス)と、フォーカスエリアのSurfaceViewにrectを描画する別のカスタムビュー(DrawingRectForFocalisationAreaViewクラス)を作成しました。
fragment_take_picture.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<customs.cameras.DrawingRectForFocalisationAreaView
android:id="@+id/drawingFocusRectangle_FragmentTakePicture"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<customs.cameras.DrawCameraOptions
android:id="@+id/takePicture_FragmentTakePicture2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@android:color/transparent"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
UpdateDrawingFocusAreaRectインタフェース
package network.callbacks;
import android.graphics.Rect;
import android.hardware.Camera;
/**
* Created by EmiG on 02.02.2017.
*/
public interface UpdateDrawingFocusAreaRect {
public void repaintRectFocusArea(final Rect touchRect);
public void takePictureOnLongPress();
}
DrawCameraOptionsクラス
package customs.cameras;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import network.callbacks.UpdateDrawingFocusAreaRect;
/**
* Created by EmiG on 18.01.2017.
*/
public class DrawCameraOptions extends View {
private Paint paint;
private UpdateDrawingFocusAreaRect callback;
private static final String TAG="TakePictureFragment2";
public DrawCameraOptions(Context context) {
super(context);
this.initComponets();
}
public void setCallback(UpdateDrawingFocusAreaRect callback) {
this.callback = callback;
}
public DrawCameraOptions(Context context, AttributeSet attrs) {
super(context, attrs);
this.initComponets();
}
public DrawCameraOptions(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.initComponets();
}
private void initComponets()
{
this.paint=new Paint(paint.ANTI_ALIAS_FLAG);
this.paint.setStyle(Paint.Style.FILL_AND_STROKE);
this.paint.setColor(Color.RED);
}
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
final int width=getWidth() - getPaddingLeft() - getPaddingRight();//of the view
final int height=getHeight() - getPaddingTop() - getPaddingBottom();
final int cx=width/2 + getPaddingLeft();
final int cy=height/2 + getPaddingTop();
final float diameter= Math.min(width, height) - paint.getStrokeWidth();
final float radious=diameter/2;
canvas.drawCircle(cx,cy,radious,this.paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
Log.i(TAG,"ACTION_UP");
if(null!=this.callback)
{
this.callback.takePictureOnLongPress();
}
break;
}
return super.onTouchEvent(event);
}
}
DrawingRectForFocalisationAreaViewクラス
package customs.cameras;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by EmiG on 25.01.2017.
*/
public class DrawingRectForFocalisationAreaView extends View {
private Paint drawingPaint;
boolean haveTouch;
private Rect touchArea;
private static final int RECT_DIMENSIONS=50;
public DrawingRectForFocalisationAreaView(Context context) {
super(context);
this.init();
}
public DrawingRectForFocalisationAreaView(Context context, AttributeSet attrs) {
super(context, attrs);
this.init();
}
public DrawingRectForFocalisationAreaView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.init();
}
private void init()
{
this.drawingPaint = new Paint();
this.drawingPaint.setColor(Color.RED);
this.drawingPaint.setStyle(Paint.Style.STROKE);
this.drawingPaint.setStrokeWidth(2);
this.haveTouch = false;
}
public void setHaveTouch(boolean t, Rect tArea){
this.drawingPaint.setColor(Color.RED);
this.haveTouch = t;
this.touchArea = tArea;
}
public void validateFocus()
{
if(Color.RED == this.drawingPaint.getColor())
{
this.drawingPaint.setColor(Color.GREEN);
this.haveTouch=true;
invalidate();
}
}
@Override
protected void onDraw(Canvas canvas) {
if(this.haveTouch && null!=canvas&& null!=this.drawingPaint){
canvas.drawRect(this.touchArea.left-RECT_DIMENSIONS, this.touchArea.top-RECT_DIMENSIONS, this.touchArea.right+RECT_DIMENSIONS, this.touchArea.bottom+RECT_DIMENSIONS, this.drawingPaint);
this.haveTouch=false;
}
}
}
TakePictureFragment2クラス
public class TakePictureFragment2 extends Fragment implements SurfaceHolder.Callback, View.OnTouchListener, UpdateDrawingFocusAreaRect {
private static final String TAG = TakePictureFragment2.class.getSimpleName();
//region Focus variabiles
private boolean bIsPictureTaking, bIsAutoFocusStarted, bIsAutoFocused, USE_AUTOFOCUS, isFocusated, isLongPressed, canTakePicture;
private static final int FOCUS_AREA_SIZE = 300;
//endregion
private boolean camCondition = false; // conditional variable for camera preview checking and set to false
//region Camera object
private Camera camera;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera.PictureCallback jpegCallback;
//endregion
//region Execute multiple calculation functionality for drawing
private ThreadPoolExecutor threadPoolExecutor;
public static final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
//endregion
//region Custom Objects that draw on the screen
private DrawCameraOptions takePictureButton;// Draw shuttbutton for capture image
//Desenare pe ecran punct de focalizare
private DrawingRectForFocalisationAreaView drawingRectangleOnScreen;//Draw blue rectangle on focus area
//endregion
//region Fragent methods
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.i(TAG, "onCreateView()");
View view = inflater.inflate(R.layout.fragment_take_picture, container, false);
if (null != view) {
return view;
}
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(TAG, "onActivityCreated()");
this.initOnTouchListener();
}
@Override
public void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
this.initComponents();
if (null != camera) {
try {
camera.setPreviewDisplay(surfaceHolder); // setting preview of camera
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//endregion
//region Initial Components
private void initOnTouchListener() {
if (null != this.getView()) {
this.getView().setOnTouchListener(TakePictureFragment2.this);
}
}
private void initComponents() {
if (null != getView()) {
this.drawingRectangleOnScreen = (DrawingRectForFocalisationAreaView) getView().findViewById(R.id.drawingFocusRectangle_FragmentTakePicture);
takePictureButton = (DrawCameraOptions) getView().findViewById(R.id.takePicture_FragmentTakePicture2);
takePictureButton.setCallback(TakePictureFragment2.this);
takePictureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG,"Simple click");
camera.takePicture(null, null, jpegCallback);
}
});
takePictureButton.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.i(TAG,"Long click");
final Context context=getView().getContext();
isLongPressed=true;
synchronized (this) {
if (camera != null) {
camera.cancelAutoFocus();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
if (!bIsPictureTaking && !bIsAutoFocusStarted) {
bIsAutoFocusStarted = true;
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
Camera.Parameters parameters = camera.getParameters();
if (parameters.getMaxNumMeteringAreas() > 0) {
Log.i(TAG, "fancy !");
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point screenDsiplay=new Point();
display.getSize(screenDsiplay);
Rect rect = calculateFocusArea(screenDsiplay.x/2, screenDsiplay.y/2);
display=null;
screenDsiplay=null;
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
meteringAreas.add(new Camera.Area(rect, 1000));
parameters.setFocusAreas(meteringAreas);
camera.setParameters(parameters);
camera.autoFocus(mAutoFocusTakePictureCallback);
} else {
camera.autoFocus(mAutoFocusTakePictureCallback);
}
bIsAutoFocusStarted = false;
} catch (Exception e) {
Log.e(TAG, "Error " + e.getMessage());
e.printStackTrace();
}
System.gc();
return null;
}
}.execute((Void[]) null);
}
} else {
if (!bIsPictureTaking && !bIsAutoFocusStarted) {
bIsAutoFocusStarted = true;
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
Camera.Parameters parameters = camera.getParameters();
if (parameters.getMaxNumMeteringAreas() > 0) {
Log.i(TAG, "fancy !");
Display display2 = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point screenDsiplay2=new Point();
display2.getSize(screenDsiplay2);
Rect rect = calculateFocusArea(screenDsiplay2.x/2, screenDsiplay2.y/2);
display2=null;
screenDsiplay2=null;
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
meteringAreas.add(new Camera.Area(rect, 1000));
parameters.setFocusAreas(meteringAreas);
camera.setParameters(parameters);
camera.autoFocus(mAutoFocusTakePictureCallback);
} else {
camera.autoFocus(mAutoFocusTakePictureCallback);
}
bIsAutoFocusStarted = false;
} catch (Exception e) {
Log.e(TAG, "Error " + e.getMessage());
e.printStackTrace();
}
System.gc();
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
}
}
}
}
return true;
}
});
surfaceView = (SurfaceView) getView().findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
surfaceHolder.addCallback(this);
jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(final byte[] data, Camera camera) {
USE_AUTOFOCUS=false;
canTakePicture=false;
final Context context = getView().getContext();
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
bIsPictureTaking = true; //set it to true to avoid onKeyDown dispatching during taking picture. it may be time-consuming
bIsAutoFocused = false; //reset to false
bIsAutoFocusStarted = false; //reset to false
FileOutputStream outStream = null;
try {
final GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTime(new Date());
final StringBuffer stringBufferFileName = new StringBuffer();
stringBufferFileName.append(gregorianCalendar.get(Calendar.YEAR));
stringBufferFileName.append("_");
stringBufferFileName.append(gregorianCalendar.get(Calendar.MONTH) + 1);
stringBufferFileName.append("_");
stringBufferFileName.append(gregorianCalendar.get(Calendar.DAY_OF_MONTH) + 1);
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "Rompetrol", stringBufferFileName.toString());
if (!root.exists()) {
root.mkdirs();
}
final File gpxfile = new File(root, System.currentTimeMillis() + ".jpg");
outStream = new FileOutputStream(gpxfile);
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
final AudioManager meng = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
if (volume != 0) {
final MediaPlayer _shootMP = MediaPlayer.create(context, Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));
_shootMP.start();
}
bIsPictureTaking = false;
JSONObject jsonObjecte = new JSONObject();
try {
jsonObjecte.put(EventBusMessages.OPERATION_TO_PERFORM.getkey(), EventBusMessages.CHANGE_FRAGMENT.getkey());
jsonObjecte.put(EventBusMessages.CHANGE_FRAGMENT.getkey(), FragmentList.DISPLAY_PICTURE_FRAGMENT.getKey());
jsonObjecte.put(EventBusMessages.PICTURE_PATH.getkey(), gpxfile.getAbsolutePath());
EventBus.getDefault().post(jsonObjecte);
} catch (JSONException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute((Void[]) null);
}
else
{
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
bIsPictureTaking = true; //set it to true to avoid onKeyDown dispatching during taking picture. it may be time-consuming
bIsAutoFocused = false; //reset to false
bIsAutoFocusStarted = false; //reset to false
FileOutputStream outStream = null;
try {
final GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTime(new Date());
final StringBuffer stringBufferFileName = new StringBuffer();
stringBufferFileName.append(gregorianCalendar.get(Calendar.YEAR));
stringBufferFileName.append("_");
stringBufferFileName.append(gregorianCalendar.get(Calendar.MONTH) + 1);
stringBufferFileName.append("_");
stringBufferFileName.append(gregorianCalendar.get(Calendar.DAY_OF_MONTH) + 1);
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "Rompetrol", stringBufferFileName.toString());
if (!root.exists()) {
root.mkdirs();
}
final File gpxfile = new File(root, System.currentTimeMillis() + ".jpg");
outStream = new FileOutputStream(gpxfile);
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
final AudioManager meng = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
if (volume != 0) {
final MediaPlayer _shootMP = MediaPlayer.create(context, Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));
_shootMP.start();
}
bIsPictureTaking = false;
JSONObject jsonObjecte = new JSONObject();
try {
jsonObjecte.put(EventBusMessages.OPERATION_TO_PERFORM.getkey(), EventBusMessages.CHANGE_FRAGMENT.getkey());
jsonObjecte.put(EventBusMessages.CHANGE_FRAGMENT.getkey(), FragmentList.DISPLAY_PICTURE_FRAGMENT.getKey());
jsonObjecte.put(EventBusMessages.PICTURE_PATH.getkey(), gpxfile.getAbsolutePath());
EventBus.getDefault().post(jsonObjecte);
} catch (JSONException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,(Void[]) null);
}
// stop preview before making changes
try {
camera.stopPreview();
surfaceView.invalidate();
surfaceHolder = null;
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
}
};
this.threadPoolExecutor = new ThreadPoolExecutor(
NUMBER_OF_CORES * 2,
NUMBER_OF_CORES * 2,
20L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
this.USE_AUTOFOCUS = false;
this.bIsPictureTaking = false; //set it to true to avoid onKeyDown dispatching during taking picture. it may be time-consuming
this.bIsAutoFocused = false; //reset to false
this.bIsAutoFocusStarted = false; //reset to false
this.isLongPressed=false;//reset to false
this.canTakePicture=false;//reset to false
}
}
//endregion
public void repaintRectFocusArea(final Rect touchRect) {
if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
drawingRectangleOnScreen.setHaveTouch(true, touchRect);
drawingRectangleOnScreen.invalidate();
} else {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
drawingRectangleOnScreen.setHaveTouch(true, touchRect);
drawingRectangleOnScreen.invalidate();
}
});
}
}
public void takePictureOnLongPress() {
if(this.isLongPressed)
{
Log.i(TAG,"ACTION_BUTTON_RELEASE");
this.isLongPressed=false;
this.canTakePicture=true;
camera.takePicture(null, null, jpegCallback);
}
}
私の悪いコードの書き込みを許しなさい。
TakePictureFragment2クラスの場合、stackoverflowはそこにあるすべてのコードを書くことができないようです。 –