Android 版本 4.4.2 三星 Note 8:我使用表面视图制作了一个自定义相机。我可能能够捕获图像并将其存储在 SD 卡中。它在我检查过的所有设备上看起来都很完美,例如 Nexus 7、Micromax Turbo、Canvas Hd、Moto G、Moto E。
但是在 samsung Note 8(4.4.2 - Kitkat) 中,图像得到了 1/8 次平铺。有时是 2/8。
当用户捕获照片并将其存储在 SdCard 文件夹中时,它包含平铺图像。像这样: http: //prntscr.com/5xoc5e
摄像头采集代码:
OnCapture 按钮单击:
camera.takePicture(null, null, mPicture);
PictureCallback mPicture = new PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
mrawDataCapturedImg = data;
try
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bmp = BitmapFactory.decodeByteArray(mrawDataCapturedImg, 0, mrawDataCapturedImg.length,options);
mimgPreview.setImageBitmap(bmp);
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
存储图像代码:
File pictureFile = new File(mediaStorageDir.getPath()
+ File.separator + saveName + ".jpg");
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(mrawDataCapturedImg);
fos.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
MyCameraPreview 类:
public class MyCameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
PreviewCallback mPreviewCallback;
AutoFocusCallback mAutoFocusCallback;
@SuppressWarnings("unused")
private String TAG = "camera";
private Activity context;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
@SuppressWarnings("deprecation")
public MyCameraPreview(Activity context, Camera camera, AutoFocusCallback autoFocusCB,PreviewCallback previewCallback)
{
super(context);
mPreviewCallback = previewCallback;
this.context = context;
this.mCamera = camera;
mAutoFocusCallback = autoFocusCB;
this.mSurfaceHolder = MyCameraPreview.this.getHolder();
this.mSurfaceHolder.addCallback(MyCameraPreview.this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height)
{
try
{
if(mCamera!=null)
{
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(parameters);
setCameraDisplayOrientation(0, mCamera);
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.setPreviewCallback(mPreviewCallback);
mCamera.startPreview();
mCamera.autoFocus(mAutoFocusCallback);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder)
{
try {
if (mCamera != null)
{
mCamera.setPreviewDisplay(surfaceHolder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder)
{
if (mCamera != null)
{
if(mAutoFocusCallback != null)
mCamera.cancelAutoFocus();
mCamera.stopPreview();
}
}
public void setCameraDisplayOrientation(
int cameraId, android.hardware.Camera camera)
{
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = context.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation)
{
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
public void setCamera(Camera camera)
{
mCamera = camera;
if (mCamera != null)
{
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
}
}
@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)
{
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
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;
}
}