【发布时间】:2016-03-16 09:19:40
【问题描述】:
我已经搜索了有关拟合相机预览和表面视图的信息,但我找不到关于在 android studio 中保存图像时不拉伸图像的信息。
相机可以很好地显示在设备的表面视图上。支持的屏幕尺寸和表面视图的比例还可以。
问题在于,在捕获图像后,它需要从屏幕表面视图的各个方面获取更多信息。它只是不采用表面视图上显示的视图,而是在保存图像时更多地显示在设备的所有侧面。
只有在表面视图的高度和支持的屏幕尺寸相等时才能解决此问题。如: 支持的尺寸是: 1280/720 表面视图是: 405/720 但这会导致限制表面视图的高度和宽度的问题。我希望表面视图的高度更长,宽度与父级匹配。
因此,如果高度不相等,问题就无法解决。我希望表面视图的高度更长,宽度与父视图匹配。
谁能帮我解决这个问题, 谢谢大家,
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private Context mContext;
private SurfaceHolder mHolder;
private Camera mCamera;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
public int measurewidth, measureheigh;
public CameraPreview(Context context, Camera camera) {
super(context);
mContext = context;
mCamera = camera;
// supported preview sizes
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
for(Camera.Size str: mSupportedPreviewSizes)
Log.e(TAG, str.width + "/" + str.height);
// 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);
}
public void surfaceCreated(SurfaceHolder holder) {
// empty. surfaceChanged will take care of stuff
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged => w=" + w + ", h=" + 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;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or reformatting changes here
// start preview with new settings
try {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width ,mPreviewSize.height); //B
// parameters.setPreviewSize(1280,720 );
mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
Log.e(TAG, "REAL SCREEN SIZE => w=" + width + ", h=" + height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
Log.e(TAG, "MPREVIEW SIZE OPTIMAL => w=" + mPreviewSize.width + ", h=" + mPreviewSize.height);
float ratio;
if(mPreviewSize.height >= mPreviewSize.width)
ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
else
ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;
Log.e(TAG, "Ration => R=" + ratio);
// One of these methods should be used, second method squishes preview slightly
//setMeasuredDimension(1080, 1200);
//setMeasuredDimension(mPreviewSize.height, mPreviewSize.width); //B
setMeasuredDimension(width, (int)(width*ratio)); //B
// setMeasuredDimension(720, 1280);
// setMeasuredDimension((int) (width ), height);
measurewidth = width ; // this is for bitmap width
measureheigh = (int)(width*ratio); // this is for bitmap height
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { // long screen
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.width - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.width - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.width - targetHeight) < minDiff) {// size.height was changed with size.width
optimalSize = size;
minDiff = Math.abs(size.width - targetHeight); // size.height was changed with size.width
}
}
}
return optimalSize;
}
}
【问题讨论】:
-
首先说明您正在使用的相机API并显示一些代码。
-
API 是 12 @haike00
-
我说的是相机 API(1 或 2),而不是 SDK 版本。
标签: android android-layout android-camera