Jak ustawić rozmiar podglądu kamery do kwadratu w widoku powierzchni do kwadratu (takim jak Instagram)
Staram się rozwijać własną aktywność kamery, ale mam problem, którego nie jestem w stanie rozwiązać...
To, czego chcę, to coś bardzo podobnego do ramki na instagram, a to jest to, co dostaję:
Kiedy powinienem dostać coś takiego:
I...
Kiedy powinienem dostać coś takiego:
Myślę, że dobrze sprawdzam SurfaceView i podgląd kamery, tylko using
Camera.Parameters parameters = camera.getParameters();
camera.setDisplayOrientation(90);
I Custom SurfaceView:
public class SquaredSurfaceView extends SurfaceView {
private int width;
private int height;
public SquaredSurfaceView(Context context) {
super(context);
}
public SquaredSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquaredSurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = width;
setMeasuredDimension(width, width);
}
public int getViewWidth() {
return width;
}
public int getViewHeight() {
return height;
}
}
Co robię źle?? :-(6 answers
Jak wspomniano wcześniej, musisz znaleźć odpowiedni rozmiar podglądu (ten z proporcjami 1: 1)i prawdopodobnie musisz użyć FrameLayout dla SurfacePreview. Wydaje się, że masz problem z proporcjami obrazu może masz odpowiedni rozmiar podglądu, ale umieszczasz go w nieprawidłowym układzie.
Innym rozwiązaniem może być (tak jak Instagram), aby aparat był w pełnym rozmiarze, a następnie ukryć niektóre obszary układu, aby wyglądał jak kwadrat. Wtedy przez oprogramowanie będziesz miał aby wyciąć obraz, aby uczynić go prawdziwym kwadratem.
Hope this helps you
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 12:40:24
Rozwiązanie, które działa dla mnie jest 2. odpowiedź, ale ponieważ musimy obrócić kamerę o 90º jest konieczne, aby zmienić szerokość z HEIGTH, coś w tym stylu...
camera.setDisplayOrientation(90);
Camera.Parameters params= camera.getParameters();
surfaceView.getLayoutParams().width=params.getPreviewSize().height;
surfaceView.getLayoutParams().height=params.getPreviewSize().width;
Mam nadzieję, że to rozwiązanie pomoże!! : D
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-31 01:15:04
Moim rozwiązaniem jest bardziej zbudowanie kwadratowej maski, a następnie umieszczenie jej na powierzchni podglądu.
Będziesz potrzebował głównie 3 rzeczy, najpierw element kwadratowej ramki. Zrobiłem Niestandardowy komponent:
package com.example.squaredviewer;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Display;
import android.view.WindowManager;
import android.widget.RelativeLayout;
/**
* Created by yadirhb on 14-08-2015.
*/
public class SquaredFrame extends RelativeLayout{
public SquaredFrame(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(size, size);
}
}
W zależności od wersji API Androida, dla której tworzysz, być może będziesz musiał dodać kolejne przeciążenie konstruktora. Dla Kitkat to jest w porządku.
Drugim krokiem jest zbudowanie układu:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:visibility="visible">
<RelativeLayout
android:id="@+id/camera_preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="false"
android:layout_centerInParent="true"
android:background="#ffffff">
</RelativeLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#131008">
</LinearLayout>
<com.example.squaredviewer.SquaredFrame
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"></com.example.squaredviewer.SquaredFrame>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#131008" />
</LinearLayout>
</RelativeLayout>
Zauważ, że RelativeLayout " camera_preview" jest używany do renderowania podglądu, jest wyśrodkowany i ma LinearLayout, który zawiera komponent squared. To jest rzeczywiście "maska" i obejmuje podgląd kamery. Zauważ również, że z wyjątkiem ramki kwadratowej, która jest przezroczysta, pozostałe dwa są w kolorze czarnym.
Teraz widok powierzchni, dla podglądu kamery, w którym powierzchnia ma rozmiar zgodny z proporcjami.
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private final String TAG = "PIC-FRAME";
private SurfaceHolder mHolder;
private Camera mCamera;
private Display display;
public CameraPreview(Activity context, Camera camera) {
super(context);
mCamera = camera;
display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setKeepScreenOn(true);
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
this.getHolder().removeCallback(this);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
try {
// stop preview before making changes
mCamera.stopPreview();
// set preview size and make any resize, rotate or
// reformatting changes here
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
// You need to choose the most appropriate previewSize for your app
Camera.Size previewSize = parametes.getSupportedPreviewSizes().get(0);
parameters.setPreviewSize(previewSize.width, previewSize.height);
// start preview with new settings
mCamera.setParameters(parameters);
// Set the holder size based on the aspect ratio
int size = Math.min(display.getWidth(), display.getHeight());
double ratio = (double) previewSize.width / previewSize.height;
mHolder.setFixedSize((int)(size * ratio), size);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
}
Teraz wszystko musi być związane w klasie aktywności
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_picture_taker);
mDecorView = getWindow().getDecorView();
//mCamera = a camera instance;
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
//Layout where camera preview is shown.
RelativeLayout preview = (RelativeLayout) findViewById(R.id.camera_preview);
//FrameLayout stack controllers inside and superpose them.
preview.addView(mPreview, 0);
// TODO
}
A trochę długo, ale mam nadzieję, że będzie to pomocne dla więcej niż jednego. :-)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-16 19:05:39
Miałem ten sam problem z widokiem kwadratowym - rozwiązałem go po prostu ustawiając Rozmiar Kamery SurfaceView na rozmiar widoku, w którym chciałem go narysować. Bez skomplikowanych obliczeń i działa dla mnie. Zobacz moją odpowiedź tutaj dla całej metody: https://stackoverflow.com/a/39430615/5181489
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
...
params.setPreviewSize(viewParams.height, viewParams.width);
camera.setParameters(params);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:56
Możesz użyć tego, aby uzyskać obraz:
public static void initialCameraPictureSize(Context context, android.hardware.Camera.Parameters parameters) {
List list = parameters.getSupportedPictureSizes();
if(list != null) {
android.hardware.Camera.Size size = null;
Iterator iterator = list.iterator();
do {
if(!iterator.hasNext())
break;
android.hardware.Camera.Size size1 = (android.hardware.Camera.Size)iterator.next();
if(Math.abs(3F * ((float)size1.width / 4F) - (float)size1.height) < 0.1F * (float)size1.width && (size == null || size1.height > size.height && size1.width < 3000))
size = size1;
} while(true);
if(size != null)
parameters.setPictureSize(size.width, size.height);
else
Log.e("CameraSettings", "No supported picture size found");
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-01 12:42:40
To takie trudne. Niełatwo.
Pierwsza rzecz: definiujesz 2 czarne Linear Layout
, aby uzyskać interfejs tak, jak napisałeś.
Druga rzecz: musisz wyciąć obraz z pełnego obrazu do kwadratu.
Jak ciąć, musisz użyć metody scaleBitmap
.
Lub chcesz prawdziwy aparat Niestandardowy? Możesz sprawdzić w tutaj
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-03 09:24:05