智能电视TV开发---拍照+水印

智能电视TV开发---录像    的基础上实现拍照功能同时修改了 智能电视TV开发---录像  里面的预览竖屏的时候,预览图像旋转了90°的问题。

一、录像实现

其实录像部分我们既可以使用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。

效果图如下:

预览界面截图:

智能电视TV开发---拍照+水印_第1张图片

实际的拍照效果:

智能电视TV开发---拍照+水印_第2张图片


二、添加水印

其实添加水印也就是获取要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;
		}
	}

效果图如下:

智能电视TV开发---拍照+水印_第3张图片

其中,上面的红色部分是我添加的水印

你可能感兴趣的:(智能电视TV开发---拍照+水印)