Мне нужно установить Mobile Vision barcode scanner с предварительным просмотром камеры в маленьком SurfaceView (1/4 высоты экрана). Как сделать это пропорционально, не сокращая предварительный просмотр камеры?Мобильное зрение на малой высоте
0
A
ответ
1
Я решил это таким образом.
Добавлен вид камеры в моей деятельности
<com.superup.smartshelf.test.CroppedCameraPreview
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Создан CroppedCameraPreview класс
public class CroppedCameraPreview extends ViewGroup {
private static final String TAG = "qwe";
private SurfaceView mSurfaceView;
private boolean mStartRequested;
private boolean mSurfaceAvailable;
private CameraSource mCameraSource;
private BarcodeDetector barcodeDetector;
public CroppedCameraPreview(final Context context, AttributeSet attrs) {
super(context, attrs);
mSurfaceView = new SurfaceView(context);
mSurfaceView.getHolder().addCallback(new SurfaceCallback());
addView(mSurfaceView);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int croppedWidth = getResources().getDisplayMetrics().widthPixels;
int croppedHeight = getResources().getDisplayMetrics().heightPixels/4;
setMeasuredDimension(croppedWidth, croppedHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// crop view
int actualPreviewWidth = getResources().getDisplayMetrics().widthPixels;
int actualPreviewHeight = getResources().getDisplayMetrics().heightPixels;
if (mSurfaceView != null) {
mSurfaceView.layout(0, 0, actualPreviewWidth, actualPreviewHeight);
}
}
public void start(CameraSource cameraSource) throws IOException {
if (cameraSource == null) {
stop();
}
mCameraSource = cameraSource;
if (mCameraSource != null) {
mStartRequested = true;
startIfReady();
}
}
public void stop() {
if (mCameraSource != null) {
mCameraSource.stop();
}
}
public void release() {
if (mCameraSource != null) {
mCameraSource.release();
mCameraSource = null;
}
}
private void startIfReady() throws IOException {
if (mStartRequested && mSurfaceAvailable) {
mCameraSource.start(mSurfaceView.getHolder());
/*if (mOverlay != null) {
Size size = mCameraSource.getPreviewSize();
int min = Math.min(size.getWidth(), size.getHeight());
int max = Math.max(size.getWidth(), size.getHeight());
if (isPortraitMode()) {
// Swap width and height sizes when in portrait, since it will be rotated by
// 90 degrees
mOverlay.setCameraInfo(min, max, mCameraSource.getCameraFacing());
} else {
mOverlay.setCameraInfo(max, min, mCameraSource.getCameraFacing());
}
mOverlay.clear();
}*/
mStartRequested = false;
}
}
private class SurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCameraSource.start(mSurfaceView.getHolder());
} catch (IOException e) {
Log.e(TAG, "Could not start camera source.", e);
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCameraSource.stop();
}
}
}
И инициализируются его в своей деятельности. setLayoutParams
позволяет задать размер представления.
CroppedCameraPreview mPreview = (CroppedCameraPreview) findViewById(R.id.preview);
// get display size
final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
//set camera view on 1/4 of the screen
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels/4);
mPreview.setLayoutParams(layoutParams);
BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(
new BarcodeTracker.NewDetectionListener() {
@Override
public void onNewDetection(Barcode barcode) {
final String rawBarcode = barcode.rawValue;
mPreview.post(new Runnable() {
public void run() {
String barcode = rawBarcode;
mediaPlayer.start();
mPreview.setVisibility(View.GONE);
Log.d(TAG, barcode);
// do all what you want with barcode
} else {
Toast.makeText(getApplicationContext(), "Barcode not found", Toast.LENGTH_SHORT).show();
}
}
});
}
});
barcodeDetector.setProcessor(new MultiProcessor.Builder<>(barcodeFactory).build());
mCameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setAutoFocusEnabled(true)
.build();
}
@Override
protected void onResume() {
super.onResume();
startCameraSource();
}
@Override
protected void onPause() {
super.onPause();
mPreview.stop();
}
@Override
protected void onDestroy() {
super.onDestroy();
mCameraSource.release();
}
private void startCameraSource() {
try {
mPreview.start(mCameraSource);
} catch (IOException e) {
Log.e(TAG, "Unable to start camera source.", e);
mCameraSource.release();
mCameraSource = null;
}
}
0
Просто используйте imageView и поместите свое изображение в атрибут src. Это сделает трюк (он имеет автомасштабирование).
Теперь, если вы хотите больше опций, вы можете использовать «android: adjustViewBounds = true» и «android: scaleType».
+0
Я отредактировал вопрос. Я прервал предварительный просмотр камеры. Необходимо установить его в правильном соотношении сторон. –
Вы можете найти примеры видеоплееров, которые регулируют размер SurfaceView и TextureView, чтобы соответствовать пропорции видео в GRAFIKA (https://github.com/google/grafika). Обратите внимание, в частности, на использование AspectFrameLayout для изменения размера SurfaceView. Мне непонятно, из вашего вопроса, если это то, что вы хотите, поскольку вы говорите о сокращении предварительного просмотра до 1/4 высоты, а затем говорите, что не хотите сжимать предварительный просмотр. – fadden