gpt4 book ai didi

android - 如何在移动视觉条码扫描器上绘制叠加层?

转载 作者:太空狗 更新时间:2023-10-29 13:50:17 25 4
gpt4 key购买 nike

我一直在努力完成这项工作,但最近几天没有成功。我正在尝试在 Mobile Vison 条形码扫描器的顶部添加一个方框覆盖(如果它也可以包含 2 个按钮会更好)。我尝试了不同的方法和解决方案,但没有成功。

最终结果应该类似于: example

谢谢!

更新

我的 xml 文件是:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:orientation="vertical">


<ui.camera.CameraSourcePreview
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ui.camera.GraphicOverlay
android:id="@+id/graphicOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</ui.camera.CameraSourcePreview>

</LinearLayout>

Java 类是:

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.CommonStatusCodes;

import data.model.Post;
import data.model.PostResponse;
import data.remote.APIService;
import data.remote.ApiUtils;
import ui.camera.CameraSource;
import ui.camera.CameraSourcePreview;

import ui.camera.GraphicOverlay;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import com.google.android.gms.vision.MultiProcessor;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;

import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public final class BarcodeCaptureActivity extends AppCompatActivity
implements BarcodeGraphicTracker.BarcodeUpdateListener {
private static final String TAG = "Barcode-reader";

private static final int RC_HANDLE_GMS = 9001;

private static final int RC_HANDLE_CAMERA_PERM = 2;

public static final String AutoFocus = "AutoFocus";
public static final String UseFlash = "UseFlash";
public static final String BarcodeObject = "Barcode";

private CameraSource mCameraSource;
private CameraSourcePreview mPreview;
private GraphicOverlay<BarcodeGraphic> mGraphicOverlay;

private ScaleGestureDetector scaleGestureDetector;
private GestureDetector gestureDetector;

private APIService mAPIService;

private Boolean codeSent;

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.barcode_capture);

codeSent = false;

mPreview = (CameraSourcePreview) findViewById(R.id.preview);
mGraphicOverlay = (GraphicOverlay<BarcodeGraphic>) findViewById(R.id.graphicOverlay);

boolean autoFocus = getIntent().getBooleanExtra(AutoFocus, false);
boolean useFlash = getIntent().getBooleanExtra(UseFlash, false);

int rc = ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if (rc == PackageManager.PERMISSION_GRANTED) {
createCameraSource(autoFocus, useFlash);
} else {
requestCameraPermission();
}

gestureDetector = new GestureDetector(this, new CaptureGestureListener());
scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener());

Snackbar.make(mGraphicOverlay, R.string.camera_info,
Snackbar.LENGTH_LONG)
.show();

mAPIService = ApiUtils.getAPIService(((BaseApplication) this.getApplication()).getBaseUrl());
}

private void requestCameraPermission() {
Log.w(TAG, "Camera permission is not granted. Requesting permission");

final String[] permissions = new String[]{Manifest.permission.CAMERA};

if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
return;
}

final Activity thisActivity = this;

View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(thisActivity, permissions,
RC_HANDLE_CAMERA_PERM);
}
};

findViewById(R.id.topLayout).setOnClickListener(listener);
Snackbar.make(mGraphicOverlay, R.string.permission_camera_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, listener)
.show();
}

@Override
public boolean onTouchEvent(MotionEvent e) {
boolean b = scaleGestureDetector.onTouchEvent(e);

boolean c = gestureDetector.onTouchEvent(e);

return b || c || super.onTouchEvent(e);
}

@SuppressLint("InlinedApi")
private void createCameraSource(boolean autoFocus, boolean useFlash) {
Context context = getApplicationContext();

BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay, this);
barcodeDetector.setProcessor(
new MultiProcessor.Builder<>(barcodeFactory).build());

if (!barcodeDetector.isOperational()) {
Log.w(TAG, "Detector dependencies are not yet available.");

IntentFilter lowStorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
boolean hasLowStorage = registerReceiver(null, lowStorageFilter) != null;

if (hasLowStorage) {
Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show();
Log.w(TAG, getString(R.string.low_storage_error));
}
}

CameraSource.Builder builder = new CameraSource.Builder(getApplicationContext(), barcodeDetector)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1600, 1024)
.setRequestedFps(15.0f);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
builder = builder.setFocusMode(
autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE : null);
}


/* mCameraSource = builder
.setFlashMode( Camera.Parameters.FLASH_MODE_AUTO)
.build();*/

mCameraSource = builder
.setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null)
.build();
}

@Override
protected void onResume() {
super.onResume();
startCameraSource();
}

@Override
protected void onPause() {
super.onPause();
if (mPreview != null) {
mPreview.stop();
}
}

@Override
protected void onDestroy() {
super.onDestroy();
if (mPreview != null) {
mPreview.release();
}
}

@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode != RC_HANDLE_CAMERA_PERM) {
Log.d(TAG, "Got unexpected permission result: " + requestCode);
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
return;
}

if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Camera permission granted - initialize the camera source");
// we have permission, so create the camerasource
boolean autoFocus = getIntent().getBooleanExtra(AutoFocus, false);
boolean useFlash = getIntent().getBooleanExtra(UseFlash, false);
createCameraSource(autoFocus, useFlash);
return;
}

Log.e(TAG, "Permission not granted: results len = " + grantResults.length +
" Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)"));

DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
};

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Multitracker sample")
.setMessage(R.string.no_camera_permission)
.setPositiveButton(R.string.ok, listener)
.show();
}

private void startCameraSource() throws SecurityException {
// check that the device has play services available.
int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
getApplicationContext());
if (code != ConnectionResult.SUCCESS) {
Dialog dlg =
GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS);
dlg.show();
}

if (mCameraSource != null) {
try {
mPreview.start(mCameraSource, mGraphicOverlay);
} catch (IOException e) {
Log.e(TAG, "Unable to start camera source.", e);
mCameraSource.release();
mCameraSource = null;
}
}
}

private boolean onTap(float rawX, float rawY) {
int[] location = new int[2];
mGraphicOverlay.getLocationOnScreen(location);
float x = (rawX - location[0]) / mGraphicOverlay.getWidthScaleFactor();
float y = (rawY - location[1]) / mGraphicOverlay.getHeightScaleFactor();

Barcode best = null;
float bestDistance = Float.MAX_VALUE;
for (BarcodeGraphic graphic : mGraphicOverlay.getGraphics()) {
Barcode barcode = graphic.getBarcode();
if (barcode.getBoundingBox().contains((int) x, (int) y)) {
best = barcode;
break;
}
float dx = x - barcode.getBoundingBox().centerX();
float dy = y - barcode.getBoundingBox().centerY();
float distance = (dx * dx) + (dy * dy); // actually squared distance
if (distance < bestDistance) {
best = barcode;
bestDistance = distance;
}
}

if (best != null) {
Intent data = new Intent();
data.putExtra(BarcodeObject, best);
setResult(CommonStatusCodes.SUCCESS, data);
finish();
return true;
}
return false;
}

private class CaptureGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return onTap(e.getRawX(), e.getRawY()) || super.onSingleTapConfirmed(e);
}
}

private class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener {

@Override
public boolean onScale(ScaleGestureDetector detector) {
return false;
}

@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}

@Override
public void onScaleEnd(ScaleGestureDetector detector) {
mCameraSource.doZoom(detector.getScaleFactor());
}
}

@Override
public void onBarcodeDetected(Barcode barcode) {
//do something with barcode data returned
Date date = new Date();

sendPost(barcode, formatDate(date));
}

private void sendPost(Barcode barcode, String date) {
if (!codeSent) {
codeSent = true;
String urlApi = ((BaseApplication) this.getApplication()).getUrl() + ((BaseApplication) this.getApplication()).getApiKey();
mAPIService.savePost(urlApi, new Post(barcode.displayValue, date)).enqueue(new Callback<PostResponse>() {
@Override
public void onResponse(Call<PostResponse> call, Response<PostResponse> response) {
codeSent = false;
if (response.isSuccessful()) {
Log.i(TAG, "post submitted to API: " + response.body().toString());
LaunchNewWin(response.body());
}
}

@Override
public void onFailure(Call<PostResponse> call, Throwable t) {
Log.e(TAG, "Unable to submit post to API.", t);
codeSent = false;
}
});
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}

private static String formatDate(Date date) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(date);
}

private void LaunchNewWin(PostResponse postResponse) {
Intent intent = new Intent(this, ResultActivity.class);
intent.putExtra("postResponse", postResponse.toString());
startActivityForResult(intent, 1);
}
}

最佳答案

我刚刚在必须自己实现二维码扫描仪时看到了您的问题。

对我来说,最简单的方法是将所有内容放在 RelativeLayout 中,然后将 View 简单地堆叠在 SurfaceView 之上。通过这样做,您可以获得所需的叠加效果。

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.activity.QRActivity">

<SurfaceView android:id="@+id/surfaceViewBarcode"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<View android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5"
android:background="@android:color/black" />

<TextView android:text="@string/qr_scanText"
android:gravity="center"
android:textColor="@android:color/white"
android:textStyle="bold"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/surfaceViewBarcode"
android:layout_alignParentTop="true"/>

唯一的不便之处在于,即使二维码未放置在指定区域,条形码扫描仪也会对其进行扫描。

关注之后this thread ,我发现您有多种选择可以达到所需的结果。一种是实现 custom processor

另一种方法是通过 BoxDetector

我觉得 this example 可以来也可以派上用场

关于android - 如何在移动视觉条码扫描器上绘制叠加层?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48826312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com