相机的连拍和水印的功能

首先介绍相机的连拍功能

说到连拍的功能,大家很容易想到就是拍照获取照片,其实这样的连拍是最常见的,不过会出现卡一下的现象,需要做类似录像截屏的操作。

下面我就简单的说明一下这种连拍的实现,都要实现无卡顿的连拍我们就不能再通过

camera.takePicture(null, null, pictureCallback);

而要换成另外的方法,

/*** <p>Installs a callback to be invoked for the next preview frame in* addition to displaying it on the screen.  After one invocation, the* callback is cleared. This method can be called any time, even when* preview is live.  Any other preview callbacks are overridden.</p>** <p>If you are using the preview data to create video or still images,* strongly consider using {@link android.media.MediaActionSound} to* properly indicate image capture or recording start/stop to the user.</p>** @param cb a callback object that receives a copy of the next preview frame,*     or null to stop receiving callbacks.* @see android.media.MediaActionSound*/
camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {/*** Called as preview frames are displayed.  This callback is invoked* on the event thread {@link #open(int)} was called from.** <p>If using the {@link android.graphics.ImageFormat#YV12} format,* refer to the equations in {@link Camera.Parameters#setPreviewFormat}* for the arrangement of the pixel data in the preview callback* buffers.** @param data the contents of the preview frame in the format defined*  by {@link android.graphics.ImageFormat}, which can be queried*  with {@link android.hardware.Camera.Parameters#getPreviewFormat()}.*  If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}*             is never called, the default will be the YCbCr_420_SP*             (NV21) format.* @param camera the Camera service object.*/@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {});

下面的方法主要不直接获取jpeg的图片流,是获取视频流格式的数据,这里只要将格式做转换即可得到数据图片,下面是转换的代码:

 Size size = camera.getParameters().getPreviewSize();Bitmap bitmap = null;try {YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);if (image != null) {ByteArrayOutputStream stream = new ByteArrayOutputStream();image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream);bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());stream.close();}} catch (Exception ex) {Log.e("Sys", "Error:" + ex.getMessage());}

这样即实现了简单的连拍功能。

相机的水印功能添加

水印添加主要是两部分,一部分是预览界面的水印,一部分是实际打到照片上的水印。

下面分开介绍:

水印旋转的秘密

上图是完成后的图片,主要的要求是水印信息要根据屏幕旋转而旋转。

这里主要是在预览的suferview上方覆盖一层水印层,然后在通过设置水印层view的参数实现,因为我这个水印会根据横屏或竖屏来变化水印的显示效果,所以会有对坐标的转换。

下面是水印文字旋转的核心代码:

private void rotateText(int orientation) {switch (orientation) {case ORIGIN:LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();lp.setMargins(0, 0, 0, 0);linearLayout.setLayoutParams(lp);linearLayout.setRotation(0);break;case LEFT:int marginRight = ll_preview_watermark.getWidth() - ll_preview_watermark.getHeight();lp = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();lp.setMargins(0, 0, marginRight, 0);linearLayout.setLayoutParams(lp);linearLayout.measure(View.MeasureSpec.makeMeasureSpec(linearLayout.getWidth() - marginRight, View.MeasureSpec.EXACTLY), 0);int hRoot = ll_preview_watermark.getHeight();int hBottom = linearLayout.getMeasuredHeight();int x1 = hBottom;int y1 = 0;int x2 = 0;int y2 = hRoot - hBottom;float[] pivot = calcPivot(x1, y1, x2, y2, false, hRoot / 2);linearLayout.setPivotX(pivot[0]);linearLayout.setPivotY(pivot[1] - y2);linearLayout.setRotation(90);break;case RIGHT:marginRight = ll_preview_watermark.getWidth() - ll_preview_watermark.getHeight();lp = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();lp.setMargins(0, 0, marginRight, 0);linearLayout.setLayoutParams(lp);linearLayout.measure(View.MeasureSpec.makeMeasureSpec(linearLayout.getWidth() - marginRight, View.MeasureSpec.EXACTLY), 0);int wRoot = ll_preview_watermark.getWidth();hRoot = ll_preview_watermark.getHeight();hBottom = linearLayout.getMeasuredHeight();x1 = 0;y1 = hRoot - hBottom;x2 = wRoot - hBottom;y2 = hRoot;pivot = calcPivot(x1, y1, x2, y2, true, wRoot / 2);linearLayout.setPivotX(pivot[0]);linearLayout.setPivotY(pivot[1] - y1);linearLayout.setRotation(-90);break;case TOP:lp = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();lp.setMargins(0, 0, 0, 0);linearLayout.setLayoutParams(lp);wRoot = ll_preview_watermark.getWidth();hRoot = ll_preview_watermark.getHeight();hBottom = linearLayout.getHeight();linearLayout.setPivotX(wRoot / 2);linearLayout.setPivotY(hBottom - hRoot / 2);linearLayout.setRotation(180);break;}}private float[] calcPivot(int x1, int y1, int x2, int y2, boolean isConstantX, int constant) {double k1 = ((double) y2 - y1) / (x2 - x1);double k2 = -1d / k1;int x3 = (x1 + x2) / 2;int y3 = (y1 + y2) / 2;double b = y3 - k2 * x3;if (isConstantX) {return new float[] {constant, (float) (k2 * constant + b)};} else {return new float[] {(float) ((constant - b) / k2), constant};}}

通过传入屏幕的四个方向的标记来做相应的旋转。

水印是如何打到照片上

方式有很多,我是用两种方式来实现的:

1.因为我这的水印信息分为两部分,一个是icon一个是文字,我之前是通过在拍照获取到的照片上,通过canvas来进行绘制的,不过如果说你的水印信息很简单,这个方法是很好的选择,以为写上去的水印清晰度很高。

2.另一种就是通过照片合成来做,不过这里遇到了比较多的问题,主要的原因是因为对图片的压缩到导致的,我简单介绍一下我这的图片合成操作,我的水印信息是一个view上承载的内容,图片是通过相机获取的,我吧水印view上的内容转换为图片在做合成即可。

下面介绍一下view获取图片的代码,

    public static Bitmap convertViewToBitmap(View view) {
//        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
// View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
//        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());view.destroyDrawingCache();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bitmap = view.getDrawingCache();
//        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
//                Bitmap.Config.ARGB_8888);
//        Canvas canvas = new Canvas(bitmap);
//        view.draw(canvas);return bitmap;}

获取到view转换过来的图片后就可以和照片进行合成了,照片和成主要是看水印在照片上的位置,

下面就是简单的工具类:

 public static Bitmap newBitmapToWatermark(Bitmap src, Bitmap watermark) {if (src == null) {return null;}int screenWidth = FSScreen.getScreenWidth();int screenHeight = FSScreen.getScreenHeight();int w = src.getWidth();int h = src.getHeight();Log.i("图片尺寸,宽", w + "--高" + h);//横着 宽: 1920--高1080//竖着 宽: 1080--高1920
//      create the new blank bitmapBitmap newb = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图,Bitmap.Config.ARGB_8888Canvas cv = new Canvas(newb);
//      draw src intocv.drawBitmap(src, 0, 0, null);// 在 0,0坐标开始画入srcif (null != watermark) {int ww = watermark.getWidth();int wh = watermark.getHeight();watermark = watermark.copy(Bitmap.Config.ARGB_8888, true);Canvas c = new Canvas(watermark);Paint p1 = new Paint();int removeColor = 0;//要去除的背景色; // store this color's int for later usep1.setAlpha(0);p1.setXfermode(new AvoidXfermode(removeColor, 0, AvoidXfermode.Mode.TARGET));c.drawPaint(p1);/**下面是绘制黑色背景,判断照片横竖**/Paint p = new Paint();//CLAMP夹紧   REPEAT重复  MIRROR镜像LinearGradient lg = newLinearGradient(0, h - wh, 0, h, Color.parseColor("#00000000"), Color.parseColor("#99000000"), Shader.TileMode.CLAMP);p.setShader(lg);if (ww > w) {float i = w / (float) ww;int result = (int) (wh * i);watermark = cropPhotoImage(src, watermark, result);cv.drawRect(0, h, screenWidth, wh, p);cv.drawBitmap(watermark, 5, h - result + 5, null);// 在src的左下角画入水印} else {cv.drawRect(0, h, screenWidth, wh, p);cv.drawBitmap(watermark, 5, h - wh + 5, null);// 在src的左下角画入水印}}// save all clipcv.save(Canvas.ALL_SAVE_FLAG);// 保存// storecv.restore();// 存储return newb;}

里面涉及到一个LinearGradient线性渐变的类,这个类可以去看官方的文档,里面介绍的比较清除,主要是通过几种模式来绘制不同样式,我这里主要是在水印的背景上绘制一个渐变的黑色背景条,防止水印打在白色区域无法看到的问题。

上面基本上就这主要和两个知识点了,如果有什么问题,欢迎反馈。

相机的连拍和水印的功能相关推荐

  1. php 怎么支持中文图片显示,利用php怎么实现一个给图片添加中文水印的功能

    利用php怎么实现一个给图片添加中文水印的功能 发布时间:2021-01-21 15:13:48 来源:亿速云 阅读:88 作者:Leah 这篇文章给大家介绍利用php怎么实现一个给图片添加中文水印的 ...

  2. Unity 相机围绕目标旋转、缩放功能实现

    Unity 相机围绕目标旋转.缩放功能实现 //************************************************相机围绕物体旋转.相机缩放*************** ...

  3. 【红外相机和普通网络摄像头夜视功能在夜视原理上的区别)】

    红外相机和普通网络摄像头夜视功能在夜视原理上的区别 提出问题 红外相机 网络摄像头的夜视功能 总结 提出问题 少则上万多则几十万红外相机夜视效果也只能看到物体或人体的轮廓特征,但是那些几十.几百块钱的 ...

  4. VS(C#)调用Basler相机SDK采集图像及基本功能设定

    注意一定要安装那个 巴斯勒的程序后在运行代码 ,要不然就报什么组建错误 注:博主看着另外一个博主的博客才有下面的一些总结,有兴趣可以看一下:https://blog.csdn.net/qq_39930 ...

  5. 互联网早报:前程无忧将上线“简历下载水印”等功能,可显示简历流向路径

    行业热点 1.前程无忧将上线"简历下载水印"等功能,可显示简历流向路径: 2.黄峥辞任拼多多董事长 将投身食品科学和生命科学领域基础研究: 3.爱奇艺正式起诉B站,涉及侵害作品信息 ...

  6. android实现自定义相机以及图片的水印

    最近在做图片的水印功能,也就研究了一下android的相机.在android中有两种方式可以进行拍照,一种是调用系统的拍照功能调用方式比较简单而且不需要权限. 调用方式: //照相机中获取照片publ ...

  7. 记录一个制作图片水印的功能

    功能介绍 对图片生成图片水印或者文字水印 ,用户可以自定义自己的图片水印 思路就是将文字和图片水印合成到一张图片上面去,前台展示合成效果 后台合成后保存到cos上面,并在数据库保存相关信息,方便用户下 ...

  8. 相机标定原理 用ROS camera_calibration 功能包 在gazebo中进行 相机校准

    在gazebo中进行相机标定 相机标定原理 相机标定意义 相机标定原理 相机标定参数 相关坐标系 世界坐标系 相机坐标系 像素坐标系.图像坐标系 相机坐标系转换为世界坐标系 像素坐标系转换为图像坐标系 ...

  9. 微信小程序调用相机选择图片生成水印

    项目近期有一个需求,是在小程序使用相机拍照时,页面缩略图和上传服务器(或保存本地)的都是带水印的,水印文案是当前的时间和当前所处的地点. 前期使用了微信小程序的wx.chooseImage相机拍照,再 ...

最新文章

  1. 阿里巴巴资深技术专家雷卷:值得开发者关注的 Java 8 后时代的语言特性
  2. activeMQ在文件上传的应用
  3. 服务器性能和活动监视
  4. spring 优越性实践
  5. Asp.Net基础 - 6.Cookie + 7.Session原理
  6. 单片机c语言程序翻译软件,单片机音乐盒翻译小程序MusicEncode软件下载
  7. A Game with Traps—— 二分
  8. 当前电子计算机发展的局限性,工程测量技术发展现状与趋势
  9. base循环解码工具
  10. IEEEtran模板使用Bibtex插入DOI不显示问题
  11. python中文开发环境_python中文开发环境
  12. 求一个整数的各个位数
  13. 安卓盒子launcher界面开发之添加自动定位,获取当地天气
  14. python如何将数据写入excel_使用python将数据写入excel
  15. 《送元二使安西》 王维渭城朝雨浥轻尘,客舍清清柳色新。劝君更尽一杯酒,西出阳关无故人。英文
  16. Android 利用广播实现黑名单【指定号码】的短信的拦截 附源码下载链接
  17. 码元、波特、速率、带宽(附例题)
  18. ionic图片点击放大,双指缩放
  19. 继 Facebook 开源 PyTorch3D 后,谷歌开源 TensorFlow 3D 场景理解库
  20. 小米7.0系统设备一键激活Xposed框架的教程

热门文章

  1. 【资料分享】地图基础知识
  2. 动态规划(练习题目)
  3. Dreamwear如何创建javascript_内存管理+如何处理4种常见的内存泄漏
  4. Spring boot (21)多数据源引起的循环引用和AutoConfigureAfter失效的问题
  5. QQ返利当当特惠活动(10.26~11.4)
  6. 程序员常说的外包公司到底是什么?
  7. 人才测评之计划能力,如何提高计划能力?
  8. 深圳盛世光影简述影视后期制作包括哪些工作?
  9. crmeb知识付费uniapp重构 适配小程序 APP 微信H5
  10. 设备树文件里的aliases和chosen