自定义相机所踩的坑,现在分享出来希望能够帮助的有需要的小伙伴

本文分享了在自定义相机过程中遇到的四个主要问题及解决方案,包括实现自动对焦、解决相机预览变形、避免内存溢出以及处理照片旋转问题。

由于项目的需要,需要在fragment们中嵌入一个自定义相机。其中在此过程中遇到了几个比较需要注意的问题下面给大家分享一下。

对于如何自定义相机我就不多说了,已经有很多人写过相关的博客。

1、如何实现自动对焦

     首先设置的属性 

  Camera.Parameters myParam =camera.getParameters();

 myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

camera.autoFocus(this);
camera.cancelAutoFocus();    //这句话一定要加上否则将不会自动对焦
2、相机预览变形
  相机预览变形的原因是由于底层返回的预览大小和你设置预览界面的大小不一致导致的,也就是surfaceview的大小(更准确的说是宽高比),而我们无法去控制底层返回预览的大小
我们能做的只有2件事情,一、改变surfaceview的大小,二、从底层返回的大小中选出一个宽高比最接近的大小设置。具体代码为:
camera.stopPreview();
Camera.Parameters parameters = camera.getParameters();
Camera.Size sizes = getBestPreviewSize(width, height);
if (sizes != null) {
    parameters.setPreviewSize(sizes.width, sizes.height);
    camera.setParameters(parameters);
}
此方法有点小瑕疵就是有可能会找不到小于0.1差值,返回就是null 所以需要在使用是先判断是否为空,或者在方法里边改进一下,具体如何改相信大家都可以
改进,容我偷个小懒就不改了。
private Camera.Size getBestPreviewSize(int width, int height) {
    Camera.Size result = null;
    final Camera.Parameters p = camera.getParameters();
    //特别注意此处需要规定rate的比是大的比小的,不然有可能出现rate = height/width。
    float rate = (float) Math.max(width, height) / (float) Math.min(width, height);
    float tmp_diff;
    float min_diff = 0.1f;
    for (Camera.Size size : p.getSupportedPreviewSizes()) {
        float current_rate = (float) Math.max(size.width, size.height) / (float) Math.min(size.width, size.height);
        tmp_diff = Math.abs(current_rate - rate);
        if (tmp_diff < min_diff) {
            min_diff = tmp_diff;
            result = size;
        }
    }
    return result;
}
经过上面的方法筛选后还有可能会有一点点变形,如果客户需要继续改进则需要改变surfaceview的大小去调节,让它能找到完全贴合的比例就可以了
3、内存溢出
这个问题可能对于许多安卓开发者都会比较头疼,因为如果应用内存溢出了那往往不是一个地方导致的,而是可能多处地方导致的。有可能是有内存泄漏了没办法及时回收,
也有可能是某些资源占用内存太大直接导出溢出。
对于内存泄漏给大家极力推荐使用leakcanary检测(谁用谁知道),检测出来了就是修改啦。
对于占用资源太大的一般来说这都是bitmap的锅,所以对于使用完bitmap之后一定要recycle()
还有一个是帧动画使用完之后记得马上clear.
除此之外我们还可以通过设置options.inSampleSize来控制bitmap返回的大小下面给出我的处理方法
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;  //此属性设置为true是将不会返回真正的bitmap,但会返回bitmap的宽和高可以通过返回的宽高去inSampleSize的值从
//而改变bimap的大小这或许是更为合理的办法,但我认为只有bitmap大小高过一定阀值才需要做此操作,但有可能第一次读取时就内存溢出了try-catch,在内存溢出时直接让他变形再次读取,不知道此方法合不合理欢迎大神指点。
mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);// data是字节数据,将其解析成位图
if (mBitmap.getByteCount() > 60 * 1024 * 1024) {    //读出bitmap先判断是否过大 如何过大则进行bitmap压缩重新读取 保存到本地时内存溢出
    options.inSampleSize = 2;
    mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
}
此外还有一个地方可能会造成内存溢出,那就是在图片保存到本地的时候下面给出我的处理的办法
try {
    fout = new FileOutputStream(jpegName);

BufferedOutputStream bos = new BufferedOutputStream(fout);
if (getBitmapSize(bmp) < 20*1024 * 1024) {
    bmp.compress(Bitmap.CompressFormat.JPEG, 95, bos);
} else if (getBitmapSize(bmp) <40* 1024 * 1024) {
    bmp.compress(Bitmap.CompressFormat.JPEG, 75, bos);
} else {
    bmp.compress(Bitmap.CompressFormat.JPEG, 55, bos);
}
bmp.recycle();
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
还是通过根据bitmap的大小来进行不同程度的压缩
4、另外有某些手机拍照保存之后照片会旋转90度,这个可以根据你自己的相机的是横向还是竖向然后去判断通过bitmap的宽高去设置旋转
if (bitmap.getWidth() > bitmap.getHeight()) {  //我的为竖屏拍照所以当宽大于高时候我把它旋转九十度
    bitmap = ImageTools.rotateToDegrees(bitmap, 90);
}
/**
 * 图片旋转
 * @param tmpBitmap
 * @param degrees
 * @return
 */
public static Bitmap rotateToDegrees(Bitmap tmpBitmap, float degrees) {
    Matrix matrix = new Matrix();
    matrix.reset();
    matrix.setRotate(degrees);
    return tmpBitmap = Bitmap.createBitmap(tmpBitmap, 0, 0, tmpBitmap.getWidth(), tmpBitmap.getHeight(), matrix,
                    false);
}

内容概要:文章以“智能网页数据标注工具”为例,深入探讨了谷歌浏览器扩展在毕业设计中的实战应用。通过开发具备实体识别、情感分类等功能的浏览器扩展,学生能够融合前端开发、自然语言处理(NLP)、本地存储与模型推理等技术,实现高效的网页数据标注系统。文中详细解析了扩展的技术架构,涵盖Manifest V3配置、内容脚本与Service Worker协作、TensorFlow.js模型在浏览器端的轻量化部署与推理流程,并提供了核心代码实现,包括文本选择、标注工具栏动态生成、高亮显示及模型预测功能。同时展望了多模态标注、主动学习与边缘计算协同等未来发展方向。; 适合人群:具备前端开发基础、熟悉JavaScript和浏览器机制,有一定AI模型应用经验的计算机相关专业本科生或研究生,尤其适合将浏览器扩展与人工智能结合进行毕业设计的学生。; 使用场景及目标:①掌握浏览器扩展开发全流程,理解内容脚本、Service Worker与弹出页的通信机制;②实现在浏览器端运行轻量级AI模型(如NER、情感分析)的技术方案;③构建可用于真实场景的数据标注工具,提升标注效率并探索主动学习、协同标注等智能化功能。; 阅读建议:建议结合代码实例搭建开发环境,逐步实现标注功能并集成本地模型推理。重点关注模型轻量化、内存管理与DOM操作的稳定性,在实践中理解浏览器扩展的安全机制与性能优化策略。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值