知方号

知方号

Android拍摄照片、视频添加水印功能

Android拍摄照片、视频添加水印功能

最近项目中需要实现拍摄照片、视频添加水印的需求,在网上找了一圈都没找到特别好用的三方,于是自己借鉴其他库实现了一个拍摄照片及视频添加水印的功能,本项目中的水印均以图片的形式添加进去!!!

先看下效果图吧(GIF图片一直上传不上去,只能演示下静态图片,动态图片可以上Github查看)

实现原理也很简单,图片水印就是将拍摄的照片转成bitmap,然后将水印内容以图片或者文字的形式绘制到一起去,视频水印通过RxFFmpeg库来实现的,该库实现的方式不是拍摄实时添加水印,而是视频拍摄好后,提供水印图片合成到视频中去的方式实现。

核心代码

/** * 绘制图片水印 */ public void stampImage(Bitmap masterBitmap, Bitmap watermark, StampPadding padding, int requestId) { int width = masterBitmap.getWidth(); int height = masterBitmap.getHeight(); Paint paint = new Paint(); paint.setFilterBitmap(true); Bitmap newBitmap = null; Canvas canvas = null; try { newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); canvas = new Canvas(newBitmap); canvas.drawBitmap(masterBitmap, 0, 0, paint); canvas.drawBitmap(watermark, padding.left, padding.top-watermark.getHeight(), paint); canvas.save(); canvas.restore(); if (mStampWatcher != null) { mStampWatcher.onSuccess(newBitmap,requestId); } } catch (Exception e) { if (mStampWatcher != null) { mStampWatcher.onError(e.getMessage(),requestId); } } } /** * 绘制文字水印 */ public void stampText(Bitmap masterBitmap, String label, int labelSize, int labelColor, StampPadding padding, int requestId) { Paint paint = new Paint(); paint.setFilterBitmap(true); paint.setDither(true); paint.setColor(labelColor); paint.setTextSize(labelSize); Bitmap newBitmap = null; Canvas canvas = null; try { Bitmap.Config config = masterBitmap.getConfig(); if (config == null) { config = Bitmap.Config.ARGB_8888; } newBitmap = masterBitmap.copy(config, true); canvas = new Canvas(newBitmap); canvas.drawText(label, padding.left, padding.top, paint);// canvas.save(Canvas.ALL_SAVE_FLAG); 在androidP上会报错,修改为canvas.save() canvas.save(); canvas.restore(); if (mStampWatcher != null) { mStampWatcher.onSuccess(newBitmap,requestId); } } catch (Exception e) { if (mStampWatcher != null) { mStampWatcher.onError(e.getMessage(),requestId); } } } /** * 添加视频水印 * rxjava方式调用 */ private void runFFmpegRxJava() { openProgressDialog(); //下面text中有三个本地地址,第一个地址为视频原文件地址,第二个地址为图片水印地址,第三个地址为添加水印后视频文件地址 final String text = "ffmpeg -y -i /storage/emulated/0/221.mp4 -i /storage/emulated/0/c3.png -filter_complex [0:v]scale=iw:ih[outv0];[1:0]scale=0.0:0.0[outv1];[outv0][outv1]overlay=0:200 -preset superfast /storage/emulated/0/1/225.mp4"; String[] commands = text.split(" "); myRxFFmpegSubscriber = new MyRxFFmpegSubscriber(this); //开始执行FFmpeg命令 RxFFmpegInvoke.getInstance().runCommandRxJava(commands).subscribe(myRxFFmpegSubscriber); } /** * 这里设为静态内部类,防止内存泄露 */ public static class MyRxFFmpegSubscriber extends RxFFmpegSubscriber { private WeakReference mWeakReference; public MyRxFFmpegSubscriber(HomeFragment homeFragment) { mWeakReference = new WeakReference(homeFragment); } @Override public void onFinish() { final HomeFragment mHomeFragment = mWeakReference.get(); if (mHomeFragment != null) { mHomeFragment.cancelProgressDialog("处理成功"); } } @Override public void onProgress(int progress, long progressTime) { final HomeFragment mHomeFragment = mWeakReference.get(); if (mHomeFragment != null) { //progressTime 可以在结合视频总时长去计算合适的进度值 mHomeFragment.setProgressDialog(progress, progressTime); } } @Override public void onCancel() { final HomeFragment mHomeFragment = mWeakReference.get(); if (mHomeFragment != null) { mHomeFragment.cancelProgressDialog("已取消"); } } @Override public void onError(String message) { final HomeFragment mHomeFragment = mWeakReference.get(); if (mHomeFragment != null) { mHomeFragment.cancelProgressDialog("出错了 onError:" + message); } } }

最后贴上GitHub地址:https://github.com/Roc0323/WatermarkShoot

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。