其实录像部分我们既可以使用Android提供的MediaRecoder也可以自己来实现,实现方式与下面的拍照功能类似,要实现PreviewCallback这个接口,具体的代码如下:
package com.jwzhangjie.smarttv_client.media.Video; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import com.jwzhangjie.smarttv_client.utils.AppLogger; import com.jwzhangjie.smarttv_client.utils.DateUtils; import android.content.Context; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.PreviewCallback; import android.os.Environment; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; public class SmartVideoSurfaceView extends SurfaceView implements Callback{ private SurfaceHolder mHolder; private Camera mCamera; private boolean previewRunning = false; private int type = 0; private String sdDir; public SmartVideoSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); initConfig(); } private void initConfig(){ mHolder = this.getHolder(); mHolder.addCallback(this); if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { sdDir = Environment.getExternalStorageDirectory().toString(); }else { sdDir = "/mnt/sdcard"; } } public Camera getVideoCamera(){ return mCamera; } public SurfaceHolder getMyHolder(){ return mHolder; } /** * 拍照功能 */ public void getPhoto(){ if (mCamera != null) { type = 0; mCamera.setOneShotPreviewCallback(pCallback); } } @Override public void surfaceCreated(SurfaceHolder holder) { try { mCamera = Camera.open(); Camera.Parameters params = mCamera.getParameters(); if (getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { params.set("orientation", "portrait"); params.set("rotation", 90); //不然预览会颠倒90° mCamera.setDisplayOrientation(90); }else { params.set("orientation", "landscape"); mCamera.setDisplayOrientation(0); } mCamera.setParameters(params); } catch (Exception e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (mCamera != null) { if (previewRunning) { mCamera.stopPreview(); } try { Camera.Parameters params = mCamera.getParameters(); params.setPreviewSize(width, height); params.setPreviewFormat(ImageFormat.JPEG); mCamera.setParameters(params); } catch (Exception e) { e.printStackTrace(); }finally{ try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); mCamera.autoFocus(null);//自动对焦 previewRunning = true; } catch (Exception e) { e.printStackTrace(); } } } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mCamera != null) { mCamera.stopPreview(); previewRunning = false; mCamera.setPreviewCallback(null); mCamera.release(); mCamera = null; } } PreviewCallback pCallback = new PreviewCallback(){ @Override public void onPreviewFrame(byte[] data, Camera camera) { switch (type) { case 0://拍照 camera.takePicture(null, null, jpeg); break; } } }; PictureCallback jpeg = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { try { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); StringBuilder builder = new StringBuilder(sdDir); builder.append("/"); builder.append(DateUtils.getCurrentTime()); builder.append(".jpeg"); AppLogger.e(builder.toString()); //自定义文件保留路径,以拍摄时间命名 File file = new File(builder.toString()); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩的流里面 bos.flush(); bos.close(); bitmap.recycle(); builder.setLength(0); builder = null; } catch (Exception e) { e.printStackTrace(); } } }; }
这里我实现的是拍照功能,所以我实现的预览回调接口是setOneShotPreviewCallback。
效果图如下:
预览界面截图:
实际的拍照效果:
其实添加水印也就是获取要Bitmap的Canvas,然后再canvas绘制内容,最后save保存,把绘制的图像保存在要添加水印的Bitmap上面,代码如下:
这里只给出修改部分的代码:
PictureCallback jpeg = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { try { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); StringBuilder builder = new StringBuilder(sdDir); builder.append("/"); builder.append(DateUtils.getCurrentTime()); builder.append(".jpg"); bitmap = createWaterMark(bitmap, null, "jwzhangjie制作"); //自定义文件保留路径,以拍摄时间命名 File file = new File(builder.toString()); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩的流里面 bos.flush(); bos.close(); bitmap.recycle(); builder.setLength(0); builder = null; } catch (Exception e) { e.printStackTrace(); } } }; /** * 添加水印效果 * @param src * @param watermark * @param title * @return */ public Bitmap createWaterMark(Bitmap src, Bitmap watermark, String title){ if (src != null) { int w = src.getWidth(); int h = src.getHeight(); //创建一个空白的画布 Bitmap tempBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888); Canvas canvas = new Canvas(tempBitmap); //在 0,0坐标开始画入src canvas.drawBitmap(src, 0, 0, null); Paint paint = new Paint(); //绘制水印 if (watermark != null) { int ww = watermark.getWidth(); int hh = watermark.getHeight(); paint.setAlpha(50); // 在src的右下角画入水印 canvas.drawBitmap(watermark, w - ww + 5, h - hh + 5, paint); } //绘制文字 if (title != null) { String familyName = "宋体"; Typeface font = Typeface.create(familyName, Typeface.BOLD); TextPaint textPaint = new TextPaint(); textPaint.setColor(Color.RED); textPaint.setTypeface(font); textPaint.setTextSize(22); //这里是自动换行 // StaticLayout layout = new StaticLayout(title, textPaint, w, Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true); // layout.draw(canvas); //文字加在中央 canvas.drawText(title, w/2, 40, textPaint); } //保存画布 canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); return tempBitmap; }else { return null; } }
效果图如下:
其中,上面的红色部分是我添加的水印