android 自定义相机 黑屏,android 自定义相机 遇到的问题

1.预览图相拉伸

2.预览黑屏

3.PictureCallback无响应

4.finish当前页面报错

首先 预览图相拉伸 是由于 SurfaceView 的尺寸 与 PreviewSize(预览尺寸) 比例不相同导致的。

解决办法 设置 预览尺寸

//设置预览尺寸

Camera.Parameters parameters = c.getParameters();

parameters.setPreviewSize(size.width, size.height);

//设置SurfaceView尺寸

Size size = mCamera.getParameters().getPreviewSize();

float scale = this.getWidth()/Float.parseFloat(size.height+"");

this.getLayoutParams().height = (int) (size.width*scale);

这样能解决 预览拉伸的问题

当然 这里 涉及到 怎么样取 合适的 预览尺寸 ,以下的网上的一个参考

/**

* 获取最适合屏幕的照片 尺寸

*

* @param sizes

* @param w

* @param h

* @return

*/

public Camera.Size getOptimalPreviewSize(List sizes, int w, int h) {

final double ASPECT_TOLERANCE = 0.1;

double targetRatio = (double) w / h;

if (sizes == null)

return null;

Camera.Size optimalSize = null;

double minDiff = Double.MAX_VALUE;

int targetHeight = h;

// Try to find an size match aspect ratio and size

for (Camera.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 (Camera.Size size : sizes) {

if (Math.abs(size.height - targetHeight) < minDiff) {

optimalSize = size;

minDiff = Math.abs(size.height - targetHeight);

}

}

}

return optimalSize;

}

具体获取“最适合的尺寸”

//先取到所有的预览尺寸,再按屏幕的宽高来获取“最适合”的尺寸

//当然如果你的SurfaceView 不是按屏幕宽高来的 你需要以SurfaceView宽高为准

//注意 因为 预览的时候 需要 旋转90度。所以这里的宽是高 高 即是宽

List sizes = parameters.getSupportedPreviewSizes();

Size size = getOptimalPreviewSize(sizes, dm.heightPixels, dm.widthPixels);

黑屏以及PictureCallback无响应 都有可能是 设置了不合适的相片尺寸 (setPictureSize)

如果想预览的内容即等于生成的相片的内容,可能需要 将 预览尺寸与相片尺寸设置相同,或者比例相同

但事不与人愿,一般来说将相片尺寸设置成 相片尺寸 不会有太大的问题,但在某些情况下是不行的。因为预览尺寸里有的尺寸 有可能 在相片尺寸中不存在,这个时候会出现 预览黑屏 或者 相机回调无响应

博主解决办法为:先获取“最适合” 屏幕的 相片尺寸,再按相片尺寸来取最“合适”的预览尺寸,根据预览的尺寸再来调整SurfaceView的尺寸

Camera c = Camera.open();

Camera.Parameters parameters = c.getParameters();

//先找最合适的照片尺寸

List pictureSizes = parameters.getSupportedPictureSizes();

Size pictureSize = getOptimalPreviewSize(pictureSizes, dm.heightPixels, dm.widthPixels);

parameters.setPictureSize(pictureSize.width,pictureSize.height);

//再找最合适的预览尺寸

List sizes = parameters.getSupportedPreviewSizes();

Size size = getOptimalPreviewSize(sizes, pictureSize.width, pictureSize.height);

parameters.setPreviewSize(size.width,size.height);

c.setParameters(parameters);

//再调整SurfaceView 宽高,注意 调整宽高得在SurfaceView能获取宽高的时候

//博主是在surfaceCreated方法中调整的

Size size = mCamera.getParameters().getPreviewSize();

float scale = this.getWidth() / Float.parseFloat(size.height + "");

this.getLayoutParams().height =(int)(size.width*scale);

既然 预览的尺寸比较与相片的尺寸比例相同,那取SurfaceView中的部分内容当然是很容易了。

首先肯定在SurfaceView层上画了一个矩形 或者 别的啥形,按图片的实际尺寸 等比缩放,然后用bitmap裁 剪即可

关键代码

PictureCallback callback = new PictureCallback() {

@Override

public void onPictureTaken(byte[] data, Camera camera) {

mCamera.setPreviewCallback(null);

mCamera.stopPreview();

releaseCamera();

//旋转90度

Bitmap bMap = BitmapFactory.decodeByteArray(data, 0, data.length);

Bitmap bMapRotate;

Matrix matrix = new Matrix();

matrix.reset();

matrix.postRotate(90);

bMapRotate = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), matrix, false);

//截取矩形内照片

ViewfinderView vf = (ViewfinderView) findViewById(R.id.viewfinder_view);

float scale = bMapRotate.getWidth() / Float.valueOf(vf.getWidth());

int width = (int) (vf.rwidth * scale);

int height = (int) (vf.rheight * scale);

bMapRotate = Bitmap.createBitmap(bMapRotate, (int) (vf.leftOffset * scale), (int) (vf.topOffset * scale), width, height);

bMap = bMapRotate;

//Intent intent = new Intent();

//intent.putExtra("data", data);

//设置返回数据

//CameraActivity.this.setResult(RESULT_OK);

CameraActivity.this.finish();

}

};

这里可能会出现finish无响应的问题,如果 将 裁剪完的bitmap 直接放入 intent中,虽然没看到报啥错,但是finish当然页面 无反应,clone 一个bitmap再传 问题依旧,博主将bitmap转成byte[] 解决了问题,但是图片过大的时候又会出现新的问题,事务过大。没法传。当然你也可能先存成文件,再传一个文件路径过去,但是如果回跳的页面中用到了bitmap 这个时候又得将file decodefile成bitmap 感觉无用功很多。 实现没办法只能推荐用静态变量的方法。博主解决为在Application中添加几个静态方法

private static Object object;

public static void set(Object obj){

Application.object = obj;

}

public static Object get(){

return Application.object;

}

@SuppressWarnings("unchecked")

public static T get(Class clazz){

return (T)Application.object;

}

public static void clear(){

Application.object = null;

}

具体使用为:

//先塞值

Application.set(bMap);

//回调页面中再取值

Bitmap bMap = Application.get(Bitmap.class);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值