Anpassen von Kamera-Ansicht für Android-mit zbar
Ich bin neu in der android Entwicklung. Meine app soll aktivieren Sie die Kamera, um einen QR-code Scannen und decodieren in die Zeichenfolge. Dies funktioniert gut, aber ich habe noch eine weitere Anforderung: um die Kamera-Ansicht in einem Rahmen und mit einem logo in einer der Ecken. Ich fand nicht eine entsprechende API in zbar sdk, um den Rahmen und befestigen Sie die logo. Das ist mein code:
ZBarScannerActivity.java:
package com.myCompany.android;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import net.sourceforge.zbar.Config;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
public class ZBarScannerActivity extends Activity implements Camera.PreviewCallback, ZBarConstants {
private static final String TAG = "ZBarScannerActivity";
private CameraPreview mPreview;
private Camera mCamera;
private ImageScanner mScanner;
private Handler mAutoFocusHandler;
private boolean mPreviewing = true;
static {
System.loadLibrary("iconv");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
mAutoFocusHandler = new Handler();
//Create and configure the ImageScanner;
setupScanner();
//Create a RelativeLayout container that will hold a SurfaceView,
//and set it as the content of our activity.
mPreview = new CameraPreview(this, this, autoFocusCB);
setContentView(mPreview);
}
public void setupScanner() {
mScanner = new ImageScanner();
mScanner.setConfig(0, Config.X_DENSITY, 3);
mScanner.setConfig(0, Config.Y_DENSITY, 3);
int[] symbols = getIntent().getIntArrayExtra(SCAN_MODES);
if (symbols != null) {
mScanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
for (int symbol : symbols) {
mScanner.setConfig(symbol, Config.ENABLE, 1);
}
//test customization
}
}
@Override
protected void onResume() {
super.onResume();
//Open the default i.e. the first rear facing camera.
mCamera = Camera.open();
mPreviewing = true;
mPreview.setCamera(mCamera);
}
@Override
protected void onPause() {
super.onPause();
//Because the Camera object is a shared resource, it's very
//important to release it when the activity is paused.
if (mCamera != null) {
mPreview.setCamera(null);
mCamera.cancelAutoFocus();
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mPreviewing = false;
mCamera = null;
}
}
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = mScanner.scanImage(barcode);
if (result != 0) {
mCamera.cancelAutoFocus();
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewing = false;
SymbolSet syms = mScanner.getResults();
for (Symbol sym : syms) {
String symData = sym.getData();
if (!TextUtils.isEmpty(symData)) {
Intent dataIntent = new Intent();
dataIntent.putExtra(SCAN_RESULT, symData);
dataIntent.putExtra(SCAN_RESULT_TYPE, sym.getType());
setResult(Activity.RESULT_OK, dataIntent);
finish();
break;
}
}
}
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if(mCamera != null && mPreviewing) {
mCamera.autoFocus(autoFocusCB);
}
}
};
//Mimic continuous auto-focusing
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
public void launchQRScanner(View v) {
if (isCameraAvailable()) {
//Toast.makeText(this, "Analyzing Image", Toast.LENGTH_LONG).show();
Intent intent = new Intent(this, ZBarScannerActivity.class);
intent.putExtra(ZBarConstants.SCAN_MODES, new int[]{Symbol.QRCODE});
startActivityForResult(intent, ZBAR_QR_SCANNER_REQUEST);
} else {
Toast.makeText(this, "Camera Unavailable", Toast.LENGTH_SHORT).show();
}
}
public boolean isCameraAvailable() {
PackageManager pm = getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.activity_qrimport_token, menu);
return true;
}
/* @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode) {
case ZBAR_SCANNER_REQUEST:
Toast.makeText(this, data.getStringExtra(ZBarConstants.SCAN_RESULT), Toast.LENGTH_LONG).show();
break;
case ZBAR_QR_SCANNER_REQUEST:
playSound();
if (resultCode == RESULT_OK) {
Toast.makeText(this, data.getStringExtra(ZBarConstants.SCAN_RESULT), Toast.LENGTH_LONG).show();
Toast.makeText(this, "Scan Result = " + data.getStringExtra(ZBarConstants.SCAN_RESULT), Toast.LENGTH_SHORT).show();
//put whatever you want to do with the code here
//TextView tv = new TextView(this);
//tv.setText(data.getStringExtra(ZBarConstants.SCAN_RESULT));
Log.d("Data",""+data.getStringExtra(ZBarConstants.SCAN_RESULT));
//setContentView(tv);
}
break;
}
}*/
/*private void playSound()
{
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.camera_shutter);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener()
{
@Override
public void onCompletion(MediaPlayer mp)
{
mp.release();
}
});
}*/
}
CameraPreview.java:
package com.myCompany.android;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import java.io.IOException;
import java.util.List;
class CameraPreview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "CameraPreview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
PreviewCallback mPreviewCallback;
AutoFocusCallback mAutoFocusCallback;
CameraPreview(Context context, PreviewCallback previewCallback, AutoFocusCallback autoFocusCb) {
super(context);
mPreviewCallback = previewCallback;
mAutoFocusCallback = autoFocusCb;
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
//Install a SurfaceHolder.Callback so we get notified when the
//underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//We purposely disregard child measurements because act as a
//wrapper to a SurfaceView that centers the camera preview instead
//of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
//Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
//The Surface has been created, acquire the camera and tell it where
//to draw.
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
//Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.cancelAutoFocus();
mCamera.stopPreview();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
//Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
//Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (holder.getSurface() == null){
//preview surface does not exist
return;
}
//Now that the size is known, set up the camera parameters and begin
//the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.setPreviewCallback(mPreviewCallback);
mCamera.startPreview();
mCamera.autoFocus(mAutoFocusCallback);
}
}
So passen Sie die Kamera-Ansicht für android? Ich sah einige empfohlene Lösungen für das iPhone, aber zbar-API für Android ist komplett anders und viel kleiner. Ich wäre dankbar um jede Idee/Tipp...
InformationsquelleAutor user2336535 | 2013-05-01
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Präsentieren ein Bild in cameraview, fügen Sie eine Bildansicht in das framelayout(camerapreview) main.xml .
Verwenden Sie diesen code, um den Rahmen(Bildansicht) sichtbar. Wie der Rahmen(Bildansicht) ist bereits in das framelayout in main.xml wir entfernen müssen Sie zuerst.
Scannen die camerapreview nur aus Ihrem Rahmen, den Sie verwenden müssen, setCrop().Passen Sie die Größe des camerapreview nach den Rahmen.
Dieser arbeitete für mich, und hoffe, es wird Ihr problem lösen zu können. Bitte entschuldigen Sie mich für meine grammatische Fehler. Danke.
src
fürImageView
, bro?android:src="@drawable/overlay"
Ich habe es mit photoshop. Eine einfache png, in denen eine kleine durchsichtige box ist geschnitten mit undurchsichtigen Mittellinie. Es ist ähnlich zu dem, was wir sehen, in pre-made-barcode-scanner.
Aber mit unterschiedliche Bildschirm-Auflösung, könnte es füllen Sie alle Bildschirm-oder Leerzeichen haben in der linken und rechten Seite
im Grunde machen Sie verschiedene overlays für verschiedene Bildschirm-Auflösungen. Auch halten die Breite und Höhe als match_parent Ihnen helfen, füllen Sie den ganzen Bildschirm. Ich hoffe, das hilft.
InformationsquelleAutor Victor
Ich denke es ist einfacher dann gedacht:
In der Beispiel code von der ZBar Kerl gibt es diese beiden Zeilen in die onCreate () - Methode:
sind verantwortlich für das hinzufügen der "Vorschau-Ansicht", um die camerPreview Layout.
Finden die genannten Zeilen in Ihren code, erstellen Sie eine neue Bildansicht und auch hinzufügen, um die Album Vorhören-Layout wie dieses:
Passen Sie die Größe und die position Ihrer anzeigen v und Sie sind fertig!
Können Sie Ihre Tätigkeit?
InformationsquelleAutor Elias
Ich vor dem gleichen problem. Die Lösung ist, fügen Sie einfach die CameraPrevie in Ihre xml in ein frameLayout, und nur nach, dass Sie das gewünschte Bild auf der Oberseite ist.
zB.:
und füllen Sie es aus Ihrer Tätigkeit:
InformationsquelleAutor MonkeyDroid