Java tutorial
/* * CameraSurface.java * ARToolKit5 * * Disclaimer: IMPORTANT: This Daqri software is supplied to you by Daqri * LLC ("Daqri") in consideration of your agreement to the following * terms, and your use, installation, modification or redistribution of * this Daqri software constitutes acceptance of these terms. If you do * not agree with these terms, please do not use, install, modify or * redistribute this Daqri software. * * In consideration of your agreement to abide by the following terms, and * subject to these terms, Daqri grants you a personal, non-exclusive * license, under Daqri's copyrights in this original Daqri software (the * "Daqri Software"), to use, reproduce, modify and redistribute the Daqri * Software, with or without modifications, in source and/or binary forms; * provided that if you redistribute the Daqri Software in its entirety and * without modifications, you must retain this notice and the following * text and disclaimers in all such redistributions of the Daqri Software. * Neither the name, trademarks, service marks or logos of Daqri LLC may * be used to endorse or promote products derived from the Daqri Software * without specific prior written permission from Daqri. Except as * expressly stated in this notice, no other rights or licenses, express or * implied, are granted by Daqri herein, including but not limited to any * patent rights that may be infringed by your derivative works or by other * works in which the Daqri Software may be incorporated. * * The Daqri Software is provided by Daqri on an "AS IS" basis. DAQRI * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION * THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE, REGARDING THE DAQRI SOFTWARE OR ITS USE AND * OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. * * IN NO EVENT SHALL DAQRI BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, * MODIFICATION AND/OR DISTRIBUTION OF THE DAQRI SOFTWARE, HOWEVER CAUSED * AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), * STRICT LIABILITY OR OTHERWISE, EVEN IF DAQRI HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Copyright 2015 Daqri, LLC. * Copyright 2011-2015 ARToolworks, Inc. * * Author(s): Julian Looser, Philip Lamb * */ package org.artoolkit.ar.samples.ARMovie; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.PixelFormat; import android.hardware.Camera; import android.os.Build; import android.preference.PreferenceManager; import android.support.v4.content.ContextCompat; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.Toast; import java.io.IOException; public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback { private static final String TAG = "CameraSurface"; private Camera camera; @SuppressWarnings("deprecation") public CameraSurface(Context context) { super(context); Log.i(TAG, "CameraSurface(): ctor called"); Activity activityRef = (Activity) context; try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activityRef, Manifest.permission.CAMERA)) { mustAskPermissionFirst = true; if (activityRef.shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) { // Will drop in here if user denied permissions access camera before. // Or no uses-permission CAMERA element is in the // manifest file. Must explain to the end user why the app wants // permissions to the camera devices. Toast.makeText(activityRef.getApplicationContext(), "App requires access to camera to be granted", Toast.LENGTH_SHORT).show(); } // Request permission from the user to access the camera. Log.i(TAG, "CameraSurface(): must ask user for camera access permission"); activityRef.requestPermissions(new String[] { Manifest.permission.CAMERA }, ARMovieActivity.REQUEST_CAMERA_PERMISSION_RESULT); return; } } } catch (Exception ex) { Log.e(TAG, "CameraSurface(): exception caught, " + ex.getMessage()); return; } SurfaceHolder holder = getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // Deprecated in API level 11. Still required for API levels <= 10. } private boolean mustAskPermissionFirst = false; public boolean gettingCameraAccessPermissionsFromUser() { return mustAskPermissionFirst; } public void resetGettingCameraAccessPermissionsFromUserState() { mustAskPermissionFirst = false; } // SurfaceHolder.Callback methods @SuppressLint("NewApi") @Override public void surfaceCreated(SurfaceHolder holder) { Log.i(TAG, "Opening camera."); try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { int cameraIndex = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(getContext()) .getString("pref_cameraIndex", "0")); camera = Camera.open(cameraIndex); } else { camera = Camera.open(); } } catch (RuntimeException exception) { Log.e(TAG, "Cannot open camera. It may be in use by another process."); } if (camera != null) { try { camera.setPreviewDisplay(holder); //camera.setPreviewCallback(this); camera.setPreviewCallbackWithBuffer(this); // API level 8 (Android 2.2) } catch (IOException exception) { Log.e(TAG, "Cannot set camera preview display."); camera.release(); camera = null; } } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (camera != null) { Log.i(TAG, "Closing camera."); camera.stopPreview(); camera.setPreviewCallback(null); camera.release(); camera = null; } } @SuppressLint("NewApi") // CameraInfo @SuppressWarnings("deprecation") // setPreviewFrameRate @Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (camera != null) { String camResolution = PreferenceManager.getDefaultSharedPreferences(getContext()).getString( "pref_cameraResolution", getResources().getString(R.string.pref_defaultValue_cameraResolution)); String[] dims = camResolution.split("x", 2); Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(Integer.parseInt(dims[0]), Integer.parseInt(dims[1])); parameters.setPreviewFrameRate(30); camera.setParameters(parameters); parameters = camera.getParameters(); int capWidth = parameters.getPreviewSize().width; int capHeight = parameters.getPreviewSize().height; int pixelformat = parameters.getPreviewFormat(); // android.graphics.imageformat PixelFormat pixelinfo = new PixelFormat(); PixelFormat.getPixelFormatInfo(pixelformat, pixelinfo); int cameraIndex = 0; boolean frontFacing = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); cameraIndex = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(getContext()) .getString("pref_cameraIndex", "0")); Camera.getCameraInfo(cameraIndex, cameraInfo); if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) frontFacing = true; } int bufSize = capWidth * capHeight * pixelinfo.bitsPerPixel / 8; // For the default NV21 format, bitsPerPixel = 12. for (int i = 0; i < 5; i++) camera.addCallbackBuffer(new byte[bufSize]); camera.startPreview(); ARMovieActivity.nativeVideoInit(capWidth, capHeight, cameraIndex, frontFacing); } } // Camera.PreviewCallback methods. @Override public void onPreviewFrame(byte[] data, Camera cam) { ARMovieActivity.nativeVideoFrame(data); cam.addCallbackBuffer(data); } }