I am developing an example application that gives me the color code of a pointed image or object through Camera in android. My application is similar to this application, and I use this application code for this.
Using this application code, I can continuously preview the preview frames, and it gives me the color code of the current preview frame. I want to be a little late. I want to get only one camera preview frame every 500 ms.
How can I do this, what kind of modification do I need to do in this code.
The code:
class Preview extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback {
public interface PreviewListener {
public void OnPreviewUpdated(int[] pixels, int width, int height);
}
PreviewListener listener;
SurfaceHolder mHolder;
Camera mCamera = null;
byte[] buffer;
int bufferSize;
private boolean isFrontCamera = false;
boolean lightOn = false;
private boolean isPaused = false;
private Parameters parameters;
private Size previewSize;
private int[] pixels;
Preview(Context context) {
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
try {
listener = (PreviewListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement PreviewListener");
}
}
public void surfaceCreated(SurfaceHolder holder) {
try {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(0, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
this.isFrontCamera = true;
}
mCamera = Camera.open(0);
}
catch (Exception e){
Log.e("camera error", "could not open camera");
return;
}
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
public void flash() {
if (supportsFlash()) {
if (!lightOn) {
lightOn = true;
mCamera.stopPreview();
mCamera.setPreviewCallbackWithBuffer(this);
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
mCamera.startPreview();
} else {
lightOn = false;
mCamera.stopPreview();
mCamera.setPreviewCallbackWithBuffer(this);
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}
public boolean supportsFlash() {
if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
parameters = mCamera.getParameters();
if (parameters.getFlashMode() != null) {
List<String> supportedFlashModes = parameters.getSupportedFlashModes();
if (supportedFlashModes == null || supportedFlashModes.isEmpty() || supportedFlashModes.size() == 1 && supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)) {
return false;
}
return true;
}
}
return false;
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
public boolean isFrontCamera() {
return isFrontCamera;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mCamera != null) {
parameters = mCamera.getParameters();
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes != null) {
if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
else if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
else if (focusModes.contains(Parameters.FOCUS_MODE_AUTO))
parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
}
int width = this.getWidth();
int height = this.getHeight();
Size best = null;
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
for (int i = 0; i < previewSizes.size(); i++) {
Size size = previewSizes.get(i);
if ((size.width <= width && size.height <= height) || (size.height <= width && size.width <= height)) {
if (best==null) {
best=size;
} else {
int resultArea=best.width*best.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
best=size;
}
}
}
}
if (best != null) {
previewSize = best;
} else {
previewSize = previewSizes.get(0);
}
parameters.setPreviewSize(previewSize.width, previewSize.height);
pixels = new int[previewSize.width * previewSize.height];
mCamera.setParameters(parameters);
mCamera.setPreviewCallbackWithBuffer(this);
bufferSize = previewSize.width*previewSize.height*ImageFormat.getBitsPerPixel(parameters.getPreviewFormat())/8;
buffer = new byte[bufferSize];
resetBuffer();
if (!isPaused) mCamera.startPreview();
}
}
public void pause(boolean isPaused) {
this.isPaused = isPaused;
if (isPaused) {
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(parameters);
mCamera.stopPreview();
} else {
if (mCamera != null) {
mCamera.setPreviewCallbackWithBuffer(this);
if(lightOn)
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
}
public void resetBuffer() {
if (mCamera != null) {
mCamera.addCallbackBuffer(buffer);
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
decodeYUV420SP(pixels, data, previewSize.width, previewSize.height);
listener.OnPreviewUpdated(pixels, previewSize.width, previewSize.height);
}
void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0)
y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0) r = 0; else if (r > 262143)
r = 262143;
if (g < 0) g = 0; else if (g > 262143)
g = 262143;
if (b < 0) b = 0; else if (b > 262143)
b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}
}
source
share