Java tutorial
/** * CameraFragment.java * @date Jan 29, 2012 * @author ricky barrette * @author Twenty Codes, LLC * * Copyright 2012 Richard Barrette * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.TwentyCodes.android.IOIOTruck; import java.io.IOException; import java.util.Iterator; import java.util.List; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.hardware.Camera; import android.hardware.Camera.Size; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; /** * This camera fragment will be used to maintain the camera, display a preview on the screen, display a vanishing point overlay on the preview * @author ricky barrette */ public class CameraFragment extends Fragment { /** * A interface used to receive steering updates generated by the camera * @author ricky barrette */ public interface CameraListener { /** * Called when there is new information * @param error * @author ricky barrette */ public void onCameraUpdate(int steeringModifier); } private boolean isDrawingView; private Camera mCamera; private Size mPreviewSize; private byte[] mImageData; private PreviewOverlay mPreviewOverlay; private SurfaceView mPreview; private CameraListener mListener; /** * Creates a new VanishingPointCameraFragment * @author ricky barrette */ public CameraFragment() { super(); } /** * (non-Javadoc) * @see android.support.v4.app.Fragment#onViewCreated(android.view.View, android.os.Bundle) * @author ricky barrette */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.camera_fragment, container, false); /* * setup augmented preview overlay */ FrameLayout fl = (FrameLayout) view.findViewById(R.id.camera_frame); mPreviewOverlay = new PreviewOverlay(this.getActivity()); fl.addView(mPreviewOverlay); /* * setup camera preview */ mPreview = (SurfaceView) view.findViewById(R.id.cameraSurface); SurfaceHolder cameraHolder = mPreview.getHolder(); cameraHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); cameraHolder.addCallback(new SurfaceHolder.Callback() { public void surfaceCreated(SurfaceHolder holder) { try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } public void surfaceDestroyed(SurfaceHolder holder) { } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } }); return view; } /** * Called when the application is resuming * (non-Javadoc) * @see android.support.v4.app.Fragment#onResume() * @author ricky barrette */ @Override public void onResume() { super.onResume(); /* * open camera */ mCamera = Camera.open(); mCamera.setDisplayOrientation(90); Camera.Parameters params = mCamera.getParameters(); /* * find smallest preview size */ List<Size> sizes = params.getSupportedPreviewSizes(); Iterator<Size> iter = sizes.iterator(); mPreviewSize = sizes.get(0); int minPixelCount = mPreviewSize.width * mPreviewSize.height; while (iter.hasNext()) { Size size = iter.next(); int pixelCount = size.height * size.width; if (pixelCount < minPixelCount) { minPixelCount = pixelCount; mPreviewSize = size; } } params.setPreviewSize(mPreviewSize.width, mPreviewSize.height); mPreviewOverlay.setPreviewSize(mPreviewSize.width, mPreviewSize.height); mImageData = new byte[mPreviewSize.width * mPreviewSize.height]; mCamera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { if (!isDrawingView) { mImageData = data; mPreviewOverlay.invalidate(); isDrawingView = true; } } }); params.setRotation(90); mCamera.setParameters(params); } /** * Called when the application is pausing * (non-Javadoc) * @see android.support.v4.app.Fragment#onPause() * @author ricky barrette */ public void onPause() { super.onPause(); mCamera.stopPreview(); mCamera.setPreviewCallback(null); mCamera.release(); } /** * @return the mError */ public void setListener(CameraListener listener) { mListener = listener; } /** * This View view will be displayed over the image preview. * It will be used to display a human readable overlay * @author ricky barrette */ private class PreviewOverlay extends View { private int imageWidth, imageHeight, mHorizonOffset; private int[] localData, edgePixels; private long lastTime; private int mVerticalOffsetLeft; private int mVerticalOffsetRight; /** * Creates a new PreviewOverlay * @param context * @author ricky barrette */ public PreviewOverlay(Context context) { super(context); lastTime = System.nanoTime(); } public void setPreviewSize(int width, int height) { ViewGroup.LayoutParams layoutParams = this.getLayoutParams(); layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; this.setLayoutParams(layoutParams); imageWidth = width; imageHeight = height; localData = new int[width * height]; edgePixels = new int[width * height]; } /** * Called by system when view is invalidated * (non-Javadoc) * @see android.view.View#onDraw(android.graphics.Canvas) * @author ricky barrette */ @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); mHorizonOffset = (this.getHeight() / 4) * 3; mVerticalOffsetLeft = this.getWidth() / 4; mVerticalOffsetRight = (this.getWidth() / 4) * 3; if (mImageData == null) return; Paint paint = new Paint(); paint.setColor(Color.RED); /* * draw the vertical & horizon lines that represent the robots path */ canvas.drawLine(0, mHorizonOffset, this.getWidth(), mHorizonOffset, paint); canvas.drawLine(mVerticalOffsetLeft, mHorizonOffset, mVerticalOffsetLeft, this.getHeight(), paint); canvas.drawLine(mVerticalOffsetRight, mHorizonOffset, mVerticalOffsetRight, this.getHeight(), paint); /* * TODO Draw boxes around objects */ /* * TODO some magical computer vision math * TODO draw path */ paint.setStrokeWidth(2); paint.setColor(Color.GREEN); /* * here is some text information */ paint.setColor(Color.RED); paint.setTextSize(30); /* * FPS */ long thisTime = System.nanoTime(); double fps = Math.floor(1e12 / (thisTime - lastTime)) / 1000; lastTime = thisTime; canvas.drawText(fps + " fps", 5, 30, paint); isDrawingView = false; } } }