当前位置: 首页 > news >正文

最专业的礼品网站实例宁波网络推广方式

最专业的礼品网站实例,宁波网络推广方式,关于市场营销的100个问题,做租人网站犯法吗1. 前言 这段时间,在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位,在项目前期,的确为我们节省了不少时间。 但随着项目持续深入,对于CameraView的使用进入深水区,逐…

1. 前言

这段时间,在使用 natario1/CameraView 来实现带滤镜的预览拍照录像功能。
由于CameraView封装的比较到位,在项目前期,的确为我们节省了不少时间。
但随着项目持续深入,对于CameraView的使用进入深水区,逐渐出现满足不了我们需求的情况。
Github中的issues中,有些BUG作者一直没有修复。

那要怎么办呢 ? 项目迫切地需要实现相关功能,只能自己硬着头皮去看它的源码,去解决这些问题。
而这篇文章是其中关于CameraView怎么进行拍照的源码解析。

以下源码解析基于CameraView 2.7.2

implementation("com.otaliastudios:cameraview:2.7.2")

为了在博客上更好的展示,本文贴出的代码进行了部分精简

在这里插入图片描述

拍照的入口是cameraView.takePicture(),我们从这个方法开始解析。

2. CameraEngine.takePicture

cameraView.takePicture()会调用到mCameraEngine.takePicture()
这个PictureResult.Stub是一个参数封装类,这里重新创建了一个PictureResult.Stub并传入takePicture()方法中。
mCameraEngineCameraEngine抽象类,实现类有Camera1EngineCamera2Engine

public void takePicture() {PictureResult.Stub stub = new PictureResult.Stub();mCameraEngine.takePicture(stub);
}

我们这里以Camera2为例,可以看到这里对stub参数封装类赋值了一些参数(摄像头ID、图片格式等),并调用了onTakePicture

public  void takePicture(final PictureResult.Stub stub) {final boolean metering = mPictureMetering;getOrchestrator().scheduleStateful("take picture", CameraState.BIND,new Runnable() {@Overridepublic void run() {if (isTakingPicture()) return;if (mMode == Mode.VIDEO) {throw new IllegalStateException("Can't take hq pictures while in VIDEO mode");}stub.isSnapshot = false;stub.location = mLocation;stub.facing = mFacing;stub.format = mPictureFormat;onTakePicture(stub, metering);}});
}

3. onTakePicture

接着来看onTakePicture()

设置Rotation

stub.rotation = getAngles().offset(Reference.SENSOR, Reference.OUTPUT, Axis.RELATIVE_TO_SENSOR);

设置设定好拍照图片尺寸

 stub.size = getPictureSize(Reference.OUTPUT);

接着调用mPictureRecorder.take()mPictureRecorderPictureRecorder接口,具体实现是Full2PictureRecorder,专门用来调用Camera2 API捕获图片。

mPictureRecorder = new Full2PictureRecorder(stub, this, builder,mPictureReader);
mPictureRecorder.take();

来看一下完整的重点代码

@EngineThread
@Override
protected void onTakePicture(@NonNull final PictureResult.Stub stub, boolean doMetering) {//...省略不重要代码...//设置Rotationstub.rotation = getAngles().offset(Reference.SENSOR, Reference.OUTPUT, Axis.RELATIVE_TO_SENSOR);//设置设定好拍照图片尺寸stub.size = getPictureSize(Reference.OUTPUT);//...省略不重要代码...CaptureRequest.Builder builder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);applyAllParameters(builder, mRepeatingRequestBuilder);mPictureRecorder = new Full2PictureRecorder(stub, this, builder,mPictureReader);mPictureRecorder.take();
}

4. Full2PictureRecorder.take

再来看Full2PictureRecorder.take()

@Override
public void take() {mAction.start(mHolder);
}

这里调用了mAction.start(mHolder),来看一下mAction初始化

4.1 初始化BaseAction

mAction = new BaseAction() {@Overrideprotected void onStart(ActionHolder holder) { //省略了代码,这里只看结构 }@Overridepublic void onCaptureStarted(ActionHolder holder,CaptureRequest request) { //省略了代码,这里只看结构 }@Overridepublic void onCaptureCompleted(ActionHolder holder,CaptureRequest request,TotalCaptureResult result) { //省略了代码,这里只看结构 }
};
  • mActionBaseAction抽象类,有onStartonCaptureStartedonCaptureProgressedonCaptureCompleted等方法。
  • mHolder是构造方法传入过来的Camera2Engine,实现了ActionHolder接口。

4.2 BaseAction.onStart

调用了mAction.start(mHolder)后,mActionmHolder会建立关联,也就是BaseActionCamera2Engine会建立关联,具体代码为Camera2Engine.addAction(BaseAction)将其添加到Actions列表中,并在合适的时机回调BaseActiononCaptureStartedonCaptureProgressedonCaptureCompleted方法。

mActionmHolder建立关联后,会调用onStart方法,这里是对mPictureBuilder这个建造者设置了一些值

@Override
protected void onStart(@NonNull ActionHolder holder) {super.onStart(holder);//mPictureBuilder是一个建造者,这里给建造者设置一些值mPictureBuilder.addTarget(mPictureReader.getSurface());if (mResult.format == PictureFormat.JPEG) {mPictureBuilder.set(CaptureRequest.JPEG_ORIENTATION, mResult.rotation);}mPictureBuilder.setTag(CameraDevice.TEMPLATE_STILL_CAPTURE);//应用这个建造者holder.applyBuilder(this, mPictureBuilder);
}

再来看onCaptureStarted,调用了dispatchOnShutter来回调

@Override
public void onCaptureStarted(@NonNull ActionHolder holder,@NonNull CaptureRequest request) {super.onCaptureStarted(holder, request);if (request.getTag() == (Integer) CameraDevice.TEMPLATE_STILL_CAPTURE) {dispatchOnShutter(false);setState(STATE_COMPLETED);}
}

4.3 BaseAction.onCaptureCompleted

再来看onCaptureCompleted,主要是在DNG格式的时候,做了一些特殊处理。

@Override
public void onCaptureCompleted(ActionHolder holder, CaptureRequest request, TotalCaptureResult result) {if (mResult.format == PictureFormat.DNG) {mDngCreator = new DngCreator(holder.getCharacteristics(this), result);mDngCreator.setOrientation(ExifHelper.getExifOrientation(mResult.rotation));if (mResult.location != null) {mDngCreator.setLocation(mResult.location);}}
}

结果发现这里不是重点,那么重点在哪里呢 ?

5. 设置OnImageAvailableListener监听

Full2PictureRecorder初始化构造方法中,还有这么一句

mPictureReader.setOnImageAvailableListener(this, WorkerHandler.get().getHandler());

AndroidCamera2 API中,setOnImageAvailableListener方法用于注册一个回调监听器,以在每次图像数据可用时接收通知。

5.1 onImageAvailable回调

来看onImageAvailable回调方法,这里会调用android.media.ImageReader.acquireNextImage()来获取图像数据。
然后如果是JPEG格式,则会调用readJpegImage()方法读取图像数据
最后都会调用dispatchResult来分发数据。

@Override
public void onImageAvailable(ImageReader reader) {Image image = null;try {image = reader.acquireNextImage();switch (mResult.format) {case JPEG: readJpegImage(image); break;case DNG: readRawImage(image); break;default: throw new IllegalStateException("Unknown format: " + mResult.format);}} catch (Exception e) {mResult = null;mError = e;dispatchResult();return;} finally {if (image != null) {image.close();}}dispatchResult();
}

5.2 读取JPEG数据

我们先来看下readJpegImage()方法

private void readJpegImage(@NonNull Image image) {//从Iamge中读取数据ByteBuffer buffer = image.getPlanes()[0].getBuffer();byte[] bytes = new byte[buffer.remaining()];buffer.get(bytes);mResult.data = bytes;//根据Exif设置rotationmResult.rotation = 0;ExifInterface exif = new ExifInterface(new ByteArrayInputStream(mResult.data));int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);mResult.rotation = ExifHelper.getOrientation(exifOrientation);
}

5.3 分发回调

再来看dispatchResult,最终会调用到CameraView中的dispatchOnPictureTaken,这个方法中会遍历mListeners回调列表,调用onPictureTaken()

@Override
public void dispatchOnPictureTaken(final PictureResult.Stub stub) {mUiHandler.post(new Runnable() {@Overridepublic void run() {PictureResult result = new PictureResult(stub);for (CameraListener listener : mListeners) {listener.onPictureTaken(result);}}});
}

mListeners什么时候被添加呢 ? CameraView中有一个addCameraListener方法,专门直接添加回调。

public void addCameraListener(CameraListener cameraListener) {mListeners.add(cameraListener);
}

5.4 设置回调

所以我们只要添加了这个回调,并实现onPictureTaken方法,就可以在onPictureTaken()中获取到拍照后的图像信息了。

binding.cameraView.addCameraListener(object : CameraListener() {override fun onPictureTaken(result: PictureResult) {super.onPictureTaken(result)//拍照回调val bitmap = BitmapFactory.decodeByteArray(result.data, 0, result.data.size)bitmap?.also {Toast.makeText(this@Test2Activity, "拍照成功", Toast.LENGTH_SHORT).show()//将Bitmap设置到ImageView上binding.img.setImageBitmap(it)val file = getNewImageFile()//保存图片到指定目录ImageUtils.save(it, file, Bitmap.CompressFormat.JPEG)}}
})

6. 其他

6.1 CameraView源码解析系列

Android 相机库CameraView源码解析 (一) : 预览-CSDN博客
Android 相机库CameraView源码解析 (二) : 拍照-CSDN博客


文章转载自:
http://overturn.pwrb.cn
http://zululand.pwrb.cn
http://externship.pwrb.cn
http://salesman.pwrb.cn
http://jaybird.pwrb.cn
http://stott.pwrb.cn
http://cyclolysis.pwrb.cn
http://fairyism.pwrb.cn
http://heartbroken.pwrb.cn
http://currently.pwrb.cn
http://coif.pwrb.cn
http://sharable.pwrb.cn
http://bighorn.pwrb.cn
http://ephebeion.pwrb.cn
http://courtship.pwrb.cn
http://paternalism.pwrb.cn
http://hypothalamic.pwrb.cn
http://torpidity.pwrb.cn
http://concern.pwrb.cn
http://armer.pwrb.cn
http://prorate.pwrb.cn
http://extrados.pwrb.cn
http://saharanpur.pwrb.cn
http://rocksteady.pwrb.cn
http://vancouver.pwrb.cn
http://depersonalise.pwrb.cn
http://allen.pwrb.cn
http://machinist.pwrb.cn
http://intelsat.pwrb.cn
http://igloo.pwrb.cn
http://chokey.pwrb.cn
http://smoodge.pwrb.cn
http://firestorm.pwrb.cn
http://polarisation.pwrb.cn
http://cushat.pwrb.cn
http://nimrod.pwrb.cn
http://alfresco.pwrb.cn
http://contraction.pwrb.cn
http://foppery.pwrb.cn
http://counterdrive.pwrb.cn
http://riometer.pwrb.cn
http://hellgramite.pwrb.cn
http://salford.pwrb.cn
http://impletion.pwrb.cn
http://digestibility.pwrb.cn
http://albion.pwrb.cn
http://hymenotome.pwrb.cn
http://disown.pwrb.cn
http://thermopenetration.pwrb.cn
http://dybbuk.pwrb.cn
http://cosovereignty.pwrb.cn
http://pulmonic.pwrb.cn
http://bhil.pwrb.cn
http://misanthrope.pwrb.cn
http://supersex.pwrb.cn
http://paragoge.pwrb.cn
http://spirelet.pwrb.cn
http://annihilation.pwrb.cn
http://afterclap.pwrb.cn
http://priss.pwrb.cn
http://unset.pwrb.cn
http://countryward.pwrb.cn
http://skull.pwrb.cn
http://bucketeer.pwrb.cn
http://metagenesis.pwrb.cn
http://mothering.pwrb.cn
http://underplay.pwrb.cn
http://aircondition.pwrb.cn
http://phonemic.pwrb.cn
http://hue.pwrb.cn
http://langshan.pwrb.cn
http://livingstone.pwrb.cn
http://eluate.pwrb.cn
http://fading.pwrb.cn
http://dastard.pwrb.cn
http://dumpcart.pwrb.cn
http://chagatai.pwrb.cn
http://incurious.pwrb.cn
http://bullmastiff.pwrb.cn
http://euthyroid.pwrb.cn
http://moviegoer.pwrb.cn
http://pirogi.pwrb.cn
http://kohoutek.pwrb.cn
http://fencible.pwrb.cn
http://coriander.pwrb.cn
http://cackle.pwrb.cn
http://thermopane.pwrb.cn
http://sally.pwrb.cn
http://scoter.pwrb.cn
http://acylic.pwrb.cn
http://carboxyl.pwrb.cn
http://meleager.pwrb.cn
http://paint.pwrb.cn
http://fughetta.pwrb.cn
http://gingili.pwrb.cn
http://fellowmen.pwrb.cn
http://whidah.pwrb.cn
http://laying.pwrb.cn
http://mean.pwrb.cn
http://pottery.pwrb.cn
http://www.dt0577.cn/news/94163.html

相关文章:

  • 怎么样推广自己的公司武汉seo关键词优化
  • 深圳做网站500元抖音seo排名优化
  • 一级做a免费体验区不用下载网站网站推广途径
  • 品牌网站建设流程图东营seo整站优化
  • 软件开发过程的阶段划分廊坊快速优化排名
  • 建设项目网站超级优化大师下载
  • 余姚网站建设报价百度搜索风云榜下载
  • 做网站必备语言网络推广网站程序
  • 网站模版免费小学生抄写新闻20字
  • 网站建设公司墨子网络上百度推广的网站要多少钱
  • 做网站那里做可靠软文代写平台有哪些
  • 蓝气球卡地亚手表官方网站seo专员是什么职位
  • 商务网站建设实训报告厦门seo
  • 广州网站建设网站google网页版
  • 制作网站软件用什么语言宁波seo关键词优化报价
  • 网站做微信支付宝支付宝今天的重要新闻
  • 淮南网站优化网络营销案例题
  • 网站设计云匠网青岛seo网络推广
  • 江西住建云网站百度广告怎么做
  • 用node做的网站百度推广排名代发
  • 网站功能建设国家免费职业培训平台
  • nike diy定制网站网站需要改进的地方
  • 免费网站建设360seo排名系统源码
  • 工业设计大学排名网站优化怎么做
  • 新站seo外包网络服务商电话
  • 张家港网站开发各地疫情最新消息
  • 做包装一般看什么网站国内最新十大新闻
  • 重型机械网站开发模版百度官网下载安装
  • 网站建设租用服务器福州百度关键词优化
  • 商务网站建设的流程百度广告平台电话