Да, это обязательно возможно. Обратите внимание, что SurfaceView
и связанные с ним Surface
- это две разные вещи, и каждому может/должен быть присвоен размер.
Surface
- это фактический буфер памяти, который будет удерживать выходной сигнал камеры, и, таким образом, его размер определяет размер фактического изображения, которое вы получите от каждого кадра. Для каждого формата, доступного с камеры, существует небольшой набор возможных (точных) размеров, которые вы можете создать в этом буфере.
SurfaceView
- это то, что отображает это изображение, когда оно доступно, и может в основном быть любого размера в вашем макете. Он будет растягивать связанные с ним данные изображения в соответствии с его размером макета, но обратите внимание, что размер этого экрана отличается от размера данных. Android автоматически изменит размер данных изображения для отображения. Это то, что, вероятно, вызывает ваше растяжение.
Например, вы можете сделать SurfaceView
основанной кнопкуШирину View, похожий на AutoFitTextureView в camera2basic, как показано ниже (это то, что я использую):
import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceView;
public class AutoFitSurfaceView extends SurfaceView {
private int mRatioWidth = 0;
private int mRatioHeight = 0;
public AutoFitSurfaceView(Context context) {
this(context, null);
}
public AutoFitSurfaceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoFitSurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
* is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
*
* @param width Relative horizontal size
* @param height Relative vertical size
*/
public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth/mRatioHeight) {
setMeasuredDimension(width, width * mRatioHeight/mRatioWidth);
} else {
setMeasuredDimension(height * mRatioWidth/mRatioHeight, height);
}
}
}
}
Похоже, что предварительный просмотр не такой размер, как вы думаете. Вы можете найти аналогичный вопрос, с некоторыми советами по использованию 'dumpsys' для изучения проблемы, в этом сообщении: http://stackoverflow.com/questions/30714469/android-supported-camera-preview-size-is-wrong- пропорции – fadden
вы нашли способ использовать SurfaceView с Camera2 и без искаженного предварительного просмотра? – vkislicins
Я переехал в TextureView - это намного более гибко. – slott