I have an Android app that opens the camera, starts preview and streams it on screen. Important note: there is no real SurfaceView
associated with the camera. There's only a dummy SurfaceTexture
:
m_previewTexture = new SurfaceTexture(58346);
camera.setPreviewTexture(m_previewTexture);
Now, I'm getting the image using the Camera.PreviewCallback
. It is irrelevant what I'm doing with it further. So far I'm displaying it on the screen, but I might as well be saving it on the memory card.
Now, the problem. I set preview size to 320x240. I get the image of 320x240 size, all seems fine. But as soon as real life objects come into the frame, I can clearly see that the image is stretched.
My activity's orientation is locked, it doesn't rotate. As I rotate the device relative to a fixed object, I can very clearly see and confirm that the image is stretched. Why could this be and how to avoid stretching?
Does your screen aspect ratio correspond to your preview's frame ratio?
Assure correct aspect ratio in onMeasure:
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
if (this.mAspectRatio == 0) {
super.onMeasure(widthSpec, heightSpec);
return;
}
int previewWidth = MeasureSpec.getSize(widthSpec);
int previewHeight = MeasureSpec.getSize(heightSpec);
int hPadding = getPaddingLeft() + getPaddingRight();
int vPadding = getPaddingTop() + getPaddingBottom();
previewWidth -= hPadding;
previewHeight -= vPadding;
boolean widthLonger = previewWidth > previewHeight;
int longSide = (widthLonger ? previewWidth : previewHeight);
int shortSide = (widthLonger ? previewHeight : previewWidth);
if (longSide > shortSide * mAspectRatio) {
longSide = (int) ((double) shortSide * mAspectRatio);
} else {
shortSide = (int) ((double) longSide / mAspectRatio);
}
if (widthLonger) {
previewWidth = longSide;
previewHeight = shortSide;
} else {
previewWidth = shortSide;
previewHeight = longSide;
}
// Add the padding of the border.
previewWidth += hPadding;
previewHeight += vPadding;
// Ask children to follow the new preview dimension.
super.onMeasure(MeasureSpec.makeMeasureSpec(previewWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(previewHeight, MeasureSpec.EXACTLY));
}
from this project