Die Kameravorschau wurde gestreckt, auch nachdem die korrekten Abmessungen festgelegt wurden
Ich bin erstellen einer Kamera-app implementiert, mit der eigenen Kamera-Vorschau bei der Aufnahme von Bildern.
Die app ist derzeit gezwungen, in den portrait-Modus.
Mein problem ist, dass die Vorschau aus der Kamera ist leicht gestreckt (das Seitenverhältnis ist ein bisschen off).
Das lustige an der Sache ist, dass ich die Einstellung meines SurfaceView Größe entspricht immer der Größe der Vorschau. Dies stellt sicher, dass das Seitenverhältnis sollte immer perserved... ist es aber nicht...
Hier ist das layout, das ich verwenden, um zu zeigen, meine Kamera-Vorschau:
public class Cp extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "CameraPreview";
private boolean mPreviewRunning = false;
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
private Size mPreviewSize;
private List<Size> mSupportedPreviewSizes;
private Camera mCamera;
public boolean IsPreviewRunning() {
return mPreviewRunning;
}
public Cp(Context context) {
this(context, null, 0);
}
public Cp(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Cp(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
//Install a SurfaceHolder.Callback so we get notified when the
//underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
requestLayout();
}
}
public void switchCamera(Camera camera) {
setCamera(camera);
try {
camera.setPreviewDisplay(mHolder);
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
camera.setParameters(parameters);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//We purposely disregard child measurements because act as a wrapper to
//a SurfaceView that
//centers the camera preview instead of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(),
widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(),
heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes == null && mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters()
.getSupportedPreviewSizes();
}
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width,
height);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.height;
previewHeight = mPreviewSize.width;
}
if (previewWidth == 0) {
previewWidth = 1;
}
if (previewHeight == 0) {
previewHeight = 1;
}
//Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height
/ previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width
/ previewWidth;
child.layout(0, (height - scaledChildHeight) / 2, width,
(height + scaledChildHeight) / 2);
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//The Surface has been created, acquire the camera and tell it where to
//draw.
try {
if (mCamera != null) {
Parameters params = mCamera.getParameters();
mSupportedPreviewSizes = params.getSupportedPreviewSizes();
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//Surface will be destroyed when we return, so stop the preview.
stop();
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
//Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
//Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mCamera != null) {
//Now that the size is known, set up the camera parameters and
//begin the preview.
Camera.Parameters parameters = mCamera.getParameters();
if (mPreviewSize != null) {
parameters.setPreviewSize(mPreviewSize.width,
mPreviewSize.height);
}
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
mPreviewRunning = true;
}
}
public void stop() {
if (mCamera != null) {
mCamera.stopPreview();
mPreviewRunning = false;
mCamera = null;
}
}
}
Bitte beachten Sie, dass in onLayout
Breite und Höhe vertauscht werden, denn die app läuft immer im hochformat.
Ich bin auch einige Bilder zeigen Ihnen, was das problem sieht wie folgt aus:
Habe ich debuggt den code. Die Größe der Vorschau ist eingestellt auf 1280x720 und die Größe des layout ist auch korrekt angepasst, die Größe.
Habe ich auch versucht, verschiedene layouts, aber das Ergebnis war immer das gleiche...
InformationsquelleAutor der Frage Paul | 2013-04-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich hatte das gleiche problem, nach einigen Tagen in dieses puzzle, meine Java-Klasse, die bis Ende diesen code ein:
So, Das problem war da, weil das Kamera-display hat eine Größe (Höhe x Breite) 576x720, und mein display war 1184x720. So, die Kamera-Vorschau (mein surface view-Klasse), der sich zu füllen, die Eltern.
So, der Ansatz, dass gearbeitet wird, um diese Ansicht größer als mein Bildschirm, und das display die Fläche von meinem Bildschirm. So, ich musste diese komischen Rahmen-Kombination (ein relative layout innerhalb eines linearlayout), so dass die Größe des relativen wird so groß sein, wie ich will - die Oberfläche anzeigen füllen wird, und die lineare nehmen nur die Teil, die will ich anzeigen.
InformationsquelleAutor der Antwort Eduardo Reis
Habe ich versucht zu lösen, das gleiche Problem... Unter code war für mich:
Können Sie sehen, der thread: Größenänderung Oberfläche anzeigen für Aspekt-Verhältnis ändern, in-video-anzeigen in android
InformationsquelleAutor der Antwort Anju
Hier ist eine Lösung
surfaceChanged ist nur, um die beste Größe der Vorschau
So wird das aufgenommene Bild auf imageReview, aber Sie brauchen eine Methode, um die rotation der bitmap
müssen Sie die Bildansicht scaleType Attribut für gestrecktes Bild Ausgabe
InformationsquelleAutor der Antwort Mohamed Embaby