/ / Възможно ли е да изрежете визуализацията на камерата? - android, android-camera

Възможно ли е да изрежете визуализацията на камерата? - андроид, андроид-камера

Не намерих никакъв начин да изрежа ppreview на камерата и след това да го покажа на SurfaceView.

Android - Възможно ли е да изрежете визуализацията на камерата?

Отговори:

6 за отговор № 1

Не директно. Camera API вече позволява компенсиране и ще изтръгне изображението на повърхността притежател. Но можете да заобиколите, като поставите наслагвания (други изгледи) върху него.


14 за отговор № 2

Можете да направите това без припокриващи изгледи (които няма да работят във всички ситуации).

Подклас ViewGroup, добавете SurfaceView като единствено дете, след това:

  1. в onMeasure предоставете изрязаните размери, които искате.
  2. в onLayout, подредете SurfaceView с необрязаните размери.

общо взето,

public class CroppedCameraPreview extends ViewGroup {
private SurfaceView cameraPreview;
public CroppedCameraPreview( Context context ) {
super( context );
// i"d probably create and add the SurfaceView here, but it doesn"t matter
}
@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
setMeasuredDimension( croppedWidth, croppedHeight );
}
@Override
protected void onLayout( boolean changed, int l, int t, int r, int b ) {
if ( cameraPreview != null ) {
cameraPreview.layout( 0, 0, actualPreviewWidth, actualPreviewHeight );
}
}
}

7 за отговор № 3

Можете да поставите предварителен преглед на камерата (SurfaceView)вътре в LinearLayout, който е вътре в ScrollView. Когато изходът на камерата е по-голям от зададения от вас LinearLayout, можете програмно да го превъртите и да деактивирате превъртането на потребителя. По този начин можете да подражавате на изрязването на камерата по лесен начин:

<ScrollView
android:id="@+id/scrollView"
android:layout_width="640dip"
android:layout_height="282dip"
android:scrollbars="none"
android:fillViewport="true">

<LinearLayout
android:id="@+id/linearLayoutBeautyContent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/surfaceViewBeautyCamera"/>
</LinearLayout>
</ScrollView>

0 за отговор № 4

Кодът за програмно превъртане на изображението би бил нещо подобно:

public void setCameraOrientationOnOpen()
{
mCamera.stopPreview();
int rotation = getRotation();
Camera.Parameters currentCameraParameters = mCamera.getParameters();
List<Camera.Size> previewSizes = currentCameraParameters.getSupportedPreviewSizes();

mOptimalCameraSize = getOptimaPreviewCameraSize(previewSizes, (double)9/16);
currentCameraParameters.setPreviewSize(mOptimalCameraSize.width, mOptimalCameraSize.height);
mCamera.setParameters(currentCameraParameters);
float ratio = 100;
int ratio1 = (mSurfaceView.getLayoutParams().height * 100) / mOptimalCameraSize.width; //height
int ratio2 = (mSurfaceView.getLayoutParams().width * 100) / mOptimalCameraSize.height; //width
ratio = Math.max(ratio1, ratio2);
mSurfaceView.getLayoutParams().height = (int) ((mOptimalCameraSize.width * ratio) / 100);
mSurfaceView.getLayoutParams().width = (int) ((mOptimalCameraSize.height * ratio) / 100);
if(ratio > 100)
{
int offset = (mSurfaceView.getLayoutParams().height - mBoxHeight)/2;
mScrollView.scrollTo(0, offset); //center the image
}
mCamera.setDisplayOrientation(rotation);
mOptimalCameraSize = mCamera.getParameters().getPreviewSize();
}

Изчислявам най-добрия размер за визуализация от камератаза полето за съдържание на камерата ми (съотношение 16: 9), след това приложете изчисленото съотношение към изображението, за да запазите същото съотношение и накрая да изчислите необходимото превъртане (изображението ще бъде в средата)


0 за отговор № 5

Създайте центрирана рамка на рамката, която ще съхранява прегледа на камерата и ще я наслагва с изгледи, за да я "изрязва". Когато създавате изгледа си, динамично разтягайте прозрачен изглед, който е центриран.

XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000" >

<FrameLayout
android:id="@+id/camera_preview_frame"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerVertical="true" />

<View
android:id="@+id/transparent_window"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_centerVertical="true"
android:background="@android:color/transparent" />

<View
android:id="@+id/black_top_box"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@id/transparent_window"
android:background="#000"/>

<View
android:id="@+id/black_bottom_box"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/transparent_window"
android:background="#000"/>
</RelativeLayout>

След това в метода OnCreate () на вашия клас на активност можете да разтегнете прозрачния изглед така.

CameraActivity.java

final View transView = findViewById(R.id.transparent_window);

transView.post(new Runnable() {

@Override
public void run() {
RelativeLayout.LayoutParams params;
params = (RelativeLayout.LayoutParams) transView.getLayoutParams();
params.height = transView.getWidth();
transView.setLayoutParams(params);
transView.postInvalidate();
}
});

Това е снимки от моя телефон на това. Сивото петно ​​в средата е гледката на камерата към пода през прозрачния изглед


0 за отговор № 6

Ето решение за ориентация = пейзаж, за да завършите @drees "отличен отговор.

Просто добавете папка оформление-земя в папка res, дублирайте целия си оформление xml и променете подредбата част от кода @drees ", за да бъде така:

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/background_dark" >

<FrameLayout
android:id="@+id/frameSurface"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@android:color/background_light"/>

<View
android:id="@+id/transparent_window"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="@android:color/transparent" />

<View
android:id="@+id/black_top_box"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@id/transparent_window"
android:background="@android:color/background_dark"/>

<View
android:id="@+id/black_bottom_box"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/transparent_window"
android:background="@android:color/background_dark"/>
</RelativeLayout>

0 за отговор № 7

Това решение е една от най-трудните задачи за вашата ситуация. Някои кодове са оттеглени и не се препоръчва за използване в корпоративни проекти, но ако трябва просто покажете предварителен преглед на камерата, без да я стискате достатъчно.
Ако имате нужда от изображение на дръжка преди визуализация, тогава трябва да погледнете SurfaceTexture

public class CameraPreview
extends SurfaceView
implements SurfaceHolder.Callback, Camera.PreviewCallback {

public static final String TAG = CameraPreview.class.getSimpleName();

private static final int PICTURE_SIZE_MAX_WIDTH = 1280;
private static final int PREVIEW_SIZE_MAX_WIDTH = 640;
private static final double ASPECT_RATIO = 3.0 / 4.0;

private Camera mCamera;
private SurfaceHolder mHolder;
private boolean mIsLive;
private boolean mIsPreviewing;

public CameraPreview(Context context) {
super(context);
init(context);
}

public CameraPreview(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int) (width / ASPECT_RATIO + 0.5);
setMeasuredDimension(width, height);
}

@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
//L.g().d(TAG, "onVisibilityChanged: visibility=" + visibility);
if (mIsLive) {
if (visibility == VISIBLE && !mIsPreviewing) {
startCameraPreview();
} else {
stopCameraPreview();
}
}
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
startCamera();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopCamera();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
//L.g().d(TAG, "surfaceChanged: format=" + format + ", width=" + w + ", height=" + h);
if (mHolder.getSurface() == null || mCamera == null) return;
mHolder = holder;
try {
mCamera.stopPreview();
} catch (Exception ignored) {}
try {
mCamera.setPreviewDisplay(mHolder);
if (mIsLive && mIsPreviewing) mCamera.startPreview();
} catch (Exception ignored) {}
}

@Override
public void onPreviewFrame(byte[] data, Camera camera) {

//work with camera preview

if (mIsPreviewing) camera.setOneShotPreviewCallback(this);
}

private Camera.Size determineBestPreviewSize(Camera.Parameters parameters) {
return determineBestSize(parameters.getSupportedPreviewSizes(), PREVIEW_SIZE_MAX_WIDTH);
}

private Camera.Size determineBestPictureSize(Camera.Parameters parameters) {
return determineBestSize(parameters.getSupportedPictureSizes(), PICTURE_SIZE_MAX_WIDTH);
}

/**
* This code I found in this repository
* https://github.com/boxme/SquareCamera/blob/master/squarecamera/src/main/java/com/desmond/squarecamera/CameraFragment.java#L368
*/
private Camera.Size determineBestSize(List<Camera.Size> sizes, int widthThreshold) {
Camera.Size bestSize = null;
Camera.Size size;
int numOfSizes = sizes.size();
for (int i = 0; i < numOfSizes; i++) {
size = sizes.get(i);
boolean isDesireRatio = (size.width / 4) == (size.height / 3);
boolean isBetterSize = (bestSize == null) || size.width > bestSize.width;

if (isDesireRatio && isBetterSize) {
bestSize = size;
}
}
if (bestSize == null) {
return sizes.get(sizes.size() - 1);
}
return bestSize;
}

private void init(Context context) {
mHolder = getHolder();
mHolder.addCallback(this);
}

public void startCamera() {
if (!mIsLive) {
//L.g().d(TAG, "startCamera");
mIsPreviewing = false;
mCamera = Camera.open();
if (mCamera != null) {
try {
Camera.Parameters param = mCamera.getParameters();
Camera.Size bestPreviewSize = determineBestPreviewSize(param);
Camera.Size bestPictureSize = determineBestPictureSize(param);
param.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
param.setPictureSize(bestPictureSize.width, bestPictureSize.height);
mCamera.setParameters(param);
} catch (RuntimeException ignored) {}
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewCallback(this);
mCamera.setPreviewDisplay(mHolder);
mIsLive = true;
} catch (Exception ignored) {}
}
//else L.g().d(TAG, "startCamera: error launching the camera");
}
}

public void stopCamera() {
if (mCamera != null && mIsLive) {
//L.g().d(TAG, "stopCamera");
mCamera.stopPreview();
mCamera.release();
mCamera = null;
mIsPreviewing = false;
mIsLive = false;
}
}

public void startCameraPreview() {
if (mCamera != null && mIsLive && !mIsPreviewing) {
//L.g().d(TAG, "startCameraPreview");
mCamera.setPreviewCallback(this);
mCamera.startPreview();
mIsPreviewing = true;
}
}

public void stopCameraPreview() {
if (mCamera != null && mIsLive && mIsPreviewing) {
//L.g().d("stopCameraPreview");
mCamera.stopPreview();
mIsPreviewing = false;
}
}
}

0 за отговор № 8

след много разглеждане през последните няколко дни вярвам, че трябва да публикувам решението си тук.

единственото, което успях да направя, и да работи добре, е да добавя мащаб.

Исках да създам Textview с част от изхода на камерата, но не можах да направя това, без да оставя прегледът да бъде мащабиран.

така че след като реша каква е най-добрата разделителна способност за съотношението на камерата / екрана, за да започна да заснемам, получавам съотношението на мащаба между височината на заснемане на камерата и височината, която искам да покажа.

mPreviewSize = chooseOptimalSize(...);

int viewHeight = getDP(this, R.dimen.videoCaptureHeight);
float scaleY = mPreviewSize.getHeight() / viewHeight;
setScaleY(scaleY);