I was trying to scan barcode using goggle vision api but am unable my app is scanning qr-codes correctly but when focusing on barcode it can't detect these is my snipe of code suggest me please:
camerapreview = (SurfaceView) findViewById(R.id.camerapreview);
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)
.build();
if (!barcodeDetector.isOperational()) {
Toast.makeText(Scanner.this, "Could not set up the detector! Update google play services", Toast.LENGTH_LONG).show();
return;
}
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.build();
//add event
camerapreview.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
cameraSource.start(camerapreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
try {
cameraSource.start(camerapreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
....................
the app is scanning qr-codes perfectly but it can't detect barcodes i can't get it working please help
You need to set the accepted formats to include "Barcode".
Specific codes to change are:
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
Replace Barcode.DATA_MATRIX | Barcode.QR_CODE with Barcode.ALL_FORMATS
Related
How to crop the SurfaceView for OCR, that OCR would be doing recognition only on the part of the photo, which is in the frame.
I used this tutorial! And for now the whole surface is recognizable. While I want to recognize only part of the whole SurfaceView, as for example in barcodes.
But still, User should have the picture of full surface.
I tried to use TextureView, but it's not compatible with CameraSouce.
private void startCameraSource() {
//Create the TextRecognizer
final TextRecognizer textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if (!textRecognizer.isOperational()) {
Log.w(TAG, "Detector dependencies not loaded yet");
} else {
//Initialize camerasource to use high resolution and set Autofocus on.
mCameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1280, 1024)
.setAutoFocusEnabled(true)
.setRequestedFps(2.0f)
.build();
/*
Add call back to SurfaceView and check if camera permission is granted.
If permission is granted we can start our cameraSource and pass it to surfaceView
*/
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if (ActivityCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraSource.start(surfaceView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCameraSource.stop();
}
});
//Set the TextRecognizer's Processor.
textRecognizer.setProcessor(new Detector.Processor<TextBlock>() {
#Override
public void release() {
}
/**
* Detect all the text from camera using TextBlock and the values into a stringBuilder
* which will then be set to the textView.
* */
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
final SparseArray<TextBlock> items = detections.getDetectedItems();
if (items.size() != 0) {
mTextView.post(new Runnable() {
#Override
public void run() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
TextBlock item = items.valueAt(i);
stringBuilder.append(item.getValue());
stringBuilder.append("\n");
}
String detectedext = stringBuilder.toString().replace("\n", "").replace("\r", "");
detectedext = detectedext.replaceAll("\\D+", "");
String comparisonResult = queryEquiNoDatabase(detectedext);
System.out.println(detectedext);
if (comparisonResult == null) {
textViewRectangle.setBackgroundResource(R.drawable.textview_border_detecting);
} else {
textViewRectangle.setBackgroundResource(R.drawable.textview_border_end);
Intent intentAfterCameraScan = new Intent(getApplicationContext(), TransformerBoxActivity.class);
intentAfterCameraScan.putExtra("equino", comparisonResult);
intentAfterCameraScan.putExtra("isOcrLast", true);
createEffect(intentAfterCameraScan, 1500);
textRecognizer.release();
}
}
});
}
}
});
}
}
The picture of the activity:
https://imgur.com/a/wc5Yjjb
What is actually recognized:
https://imgur.com/5LkmFzH
And I expect to recognize only thing which are inside the borders
For now the whole surface is applied for recognition.
I'm creating barcode reading application using google vision and it consists a flash on/off function also. i was able to implement flash using "CameraManager" like in the following code due to the "Camera" is now deprecated.but when camera screen is on, flash light is not working.when camera is freeze(when barcode is detected i'm stoping the camerasource), flash light is working. but i want to flash light on/off with out regarding the camera view is on or stop.i need this get done without using the deprecated APIs.can some one tell me how i can get solved this problem. thanks in advance.
private void setupBarcode(){
cameraPreview = (SurfaceView) findViewById(R.id.cameraPreview);
txtResult = findViewById(R.id.txtResult);
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setAutoFocusEnabled(true)
.build();
//Add Event
cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//Request permission
ActivityCompat.requestPermissions(ScanActivity.this,
new String[]{Manifest.permission.CAMERA}, RequestCameraPermissionID);
return;
}
try {
cameraSource.start(cameraPreview.getHolder());
txtResult.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> qrcodes = detections.getDetectedItems();
if (qrcodes.size() != 0) {
txtResult.post(new Runnable() {
#Override
public void run() {
okButton.setEnabled(true);
txtResult.setText(qrcodes.valueAt(0).displayValue);
cameraSource.stop();
}
});
}
}
});
}
private void flashLightOn() {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = cameraManager.getCameraIdList()[0];
cameraManager.setTorchMode(cameraId, true);
} catch (CameraAccessException e) {
}
}
Use the open source 'CameraSource.java' file from goole vision library in your project.
Get file from here
And then use the following code:
public void switchFlashLight(boolean status) {
cameraSource.setFlashMode(status ? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF);
}
I am designing an app where i scan the text using the camera and use that text to fetch more details. To do that i am using Google's vision API. But by default the API reads all the text that is available on the image as shown below.
As you can see from the above image the app is recognizing all the text that is available in front of the camera. But i would like to just scan "Hello World" from the camera. Is it possible to use some kind of touch event just to focus on the desired text
Please find the code used for text recognition
private void startCameraSource() {
//Create the TextRecognizer
final TextRecognizer textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if (!textRecognizer.isOperational()) {
Log.w(TAG, "Detector dependencies not loaded yet");
} else {
//Initialize camerasource to use high resolution and set Autofocus on.
mCameraSource = new CameraSource.Builder(getApplicationContext(), textRecognizer)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1280, 1024)
.setAutoFocusEnabled(true)
.setRequestedFps(2.0f)
.build();
/**
* Add call back to SurfaceView and check if camera permission is granted.
* If permission is granted we can start our cameraSource and pass it to surfaceView
*/
mCameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
if (ActivityCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA},
requestPermissionID);
return;
}
mCameraSource.start(mCameraView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCameraSource.stop();
}
});
//Set the TextRecognizer's Processor.
textRecognizer.setProcessor(new Detector.Processor<TextBlock>() {
#Override
public void release() {
}
/**
* Detect all the text from camera using TextBlock and the values into a stringBuilder
* which will then be set to the textView.
* */
#Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
final SparseArray<TextBlock> items = detections.getDetectedItems();
if (items.size() != 0 ){
mTextView.post(new Runnable() {
#Override
public void run() {
StringBuilder stringBuilder = new StringBuilder();
for(int i=0;i<items.size();i++){
TextBlock item = items.valueAt(i);
stringBuilder.append(item.getValue());
stringBuilder.append("\n");
}
mTextView.setText(stringBuilder.toString());
}
});
}
}
});
}
}
I have used the Camera2 API to implement a background video recorder running as a service and recording from the front cam. For this I have created a new SurfaceView, set its size to 1x1 and moved it to the top left corner. My code is shown below. I'm using Android 5.1.
With the Camera API it worked very well but unfortunately the frame rate is only at 20 fps (and when I increase the exposure compensation it drops even more), although with the Open Camera app I have 30 fps also with increased exposure compensation. That is why I want to try Camera2 API (hoping to get higher fps). Unfortunately, I'm getting the following error:
MediaRecoder: setOutputFile called in an invalid state(2)
MediaRecorder: start called in an invalid state: 2
Here is my code:
public class RecorderServiceCamera2 extends Service implements SurfaceHolder.Callback {
private WindowManager windowManager;
private SurfaceView surfaceView;
private CameraDevice mCamera;
private MediaRecorder mediaRecorder = null;
private CaptureRequest mCaptureRequest;
private CameraCaptureSession mSession;
#Override
public void onCreate() {
// Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback
windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
surfaceView = new SurfaceView(this);
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
1, 1,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT
);
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
windowManager.addView(surfaceView, layoutParams);
surfaceView.getHolder().addCallback(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
//.setSmallIcon(R.mipmap.app_icon)
.setContentTitle("Background Video Recorder")
.setContentText("")
.setContentIntent(pendingIntent).build();
startForeground(MainActivity.NOTIFICATION_ID_RECORDER_SERVICE, notification);
return Service.START_NOT_STICKY;
}
#Override
public void surfaceCreated(final SurfaceHolder surfaceHolder) {
mediaRecorder = new MediaRecorder();
try {
CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE);
String[] cameras = manager.getCameraIdList();
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameras[1]);
StreamConfigurationMap configs = characteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizes = configs.getOutputSizes(MediaCodec.class);
final Size sizeHigh = sizes[0];
manager.openCamera(cameras[1], new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice camera) {
mCamera = camera;
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setMaxFileSize(0);
mediaRecorder.setOrientationHint(0);
mediaRecorder.setOutputFile("test.mp4");
try { mediaRecorder.prepare(); } catch (Exception ignored) {}
List<Surface> list = new ArrayList<>();
list.add(surfaceHolder.getSurface());
try {
CaptureRequest.Builder captureRequest = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
captureRequest.addTarget(surfaceHolder.getSurface());
mCaptureRequest = captureRequest.build();
} catch (CameraAccessException e) {
e.printStackTrace();
}
try {
mCamera.createCaptureSession(list, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession session) {
mSession = session;
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession session) {
mSession = session;
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
mediaRecorder.start();
try {
mSession.setRepeatingRequest(mCaptureRequest,
new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureStarted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, long timestamp, long frameNumber) {
super.onCaptureStarted(session, request, timestamp, frameNumber);
}
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
}
#Override
public void onCaptureFailed(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull CaptureFailure failure) {
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
#Override
public void onDisconnected(#NonNull CameraDevice camera) {
}
#Override
public void onError(#NonNull CameraDevice camera, int error) {
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
// Stop recording and remove SurfaceView
#Override
public void onDestroy() {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
mCamera.close();
mediaRecorder= null;
windowManager.removeView(surfaceView);
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {}
#Override
public IBinder onBind(Intent intent) { return null; }
}
You don't need to put up a SurfaceView with Camera2, or even with Camera1 (with the latter, just create a SurfaceTexture to get a Surface from, and never call updateTexImage; with the former, just don't include a preview Surface at all, it's not needed).
That said, you're trying to use the same Surface in both Camera2 and the MediaRecorder; that doesn't work. MediaRecorder doesn't need to draw to a Surface at all to record, you can just leave that part off. It's only there to allow MediaRecorder to be used independently of the camera API, where it manages a camera behind the scenes.
I suspect the call to MediaRecorder.prepare() is throwing an error that you're ignoring, about the preview Surface already being in use, which is why start doesn't later work.
And yes, as CommonsWare says, you likely will need a foreground service in Android P.
help mi with this, im making a aplication that use the camera and flash a qr code but the camera dont reponse i have this code im trying first to see something with the camera and the i will work with the recognition of the QR code any help will be good
public class activity_flashqr_normalscreensize extends Activity implements
SurfaceHolder.Callback {
private Button boton;
private SurfaceView VisorQR;
SurfaceHolder surfaceHolder;
android.hardware.Camera theCamera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flashqr_normalscreensize_esp);
boton = (Button)findViewById(R.id.btnfoto);
VisorQR = (SurfaceView)findViewById(R.id.visorqr);
surfaceHolder = VisorQR.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
return;
}
try {
theCamera.stopPreview();
}
catch (Exception e) {
}
try {
theCamera.setPreviewDisplay(surfaceHolder);
theCamera.startPreview();
}
catch (Exception e) {
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
theCamera.lock();
theCamera = android.hardware.Camera.open();
}
catch (RuntimeException e) {
System.err.println(e);
return;
}
android.hardware.Camera.Parameters param;
param = theCamera.getParameters();
param.setPreviewSize(350, 250);
theCamera.setParameters(param);
try {
theCamera.setPreviewDisplay(surfaceHolder);
theCamera.startPreview();
}
catch (Exception e) {
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
theCamera.stopPreview();
theCamera.release();
theCamera = null;
}
}
i found a good tutorial to achive what i want here
http://www.codepool.biz/how-to-implement-a-simple-barcode-scan-application-on-android.html
also to use the zxing library u need to add this to the build.gradle.app
in dependedencies on android studio
compile 'com.journeyapps:zxing-android-embedded:3.2.0#aar'
compile 'com.google.zxing:core:3.2.1'