我需要在拍照时保存叠加图像,叠加是其他类视图并添加到相机预览中,这是我的代码
主要活动
public class MainActivity extends Activity implements PictureCallback{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//al pulsar el boton de realizar la foto
public void takePhoto(View button){
((CameraPreview)findViewById(R.id.camera_preview)).getCamera().takePicture(null, null, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
//archivo donde se guardara la foto
String photoPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/mifoto.jpg";
//Guardamos el archivo
try{
FileOutputStream fos= new FileOutputStream(photoPath);
fos.write(data);
fos.close();
}catch (IOException e){
Toast.makeText(this, "No se puede guardar el archivo.", Toast.LENGTH_LONG).show();
}
// si se guarda la foto
Toast.makeText(this, "La foto se guardo en: " + photoPath, Toast.LENGTH_LONG).show();
//Muestra la imagen en miniatura
Bitmap bitmap = BitmapFactory.decodeFile(photoPath);
((ImageView)findViewById(R.id.imageView)).setImageBitmap(bitmap);
}
CameraPreview 在该方法中实现类camerapreview并添加叠加图像
public class CameraPreview extends FrameLayout implements SurfaceHolder.Callback{
//Vista sobre la que se mostrara la vista previa
private SurfaceView surfaceView;
//Cámara
private Camera camera;
//Identificadores de la camara
private final int REAR_CAMERA = 0;
private final int FRONT_CAMERA = 1;
private int activeCameraId = REAR_CAMERA;
public CameraPreview(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
//Obtenemos la camara
createCamera();
//En caso de no haber camara no se hace nada
if(camera==null){
return;
}
//crear la vista y añadirla al layout
surfaceView = new SurfaceView(context);
addView(surfaceView);
//añadimos el escuchador a la vista
SurfaceHolder holder = surfaceView.getHolder();
holder.addCallback(this);
//Cosas del sdk antiguo
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.setKeepScreenOn(true);
//Añadimos el marco a la vista
Marco drawontop = new Marco(context);
addView(drawontop, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
drawontop.setVisibility(View.VISIBLE);
drawontop.bringToFront();
}
private void createCamera(){
//Si ya habia camara la libero
if(camera!=null){
camera.stopPreview();
camera.release();
}
//Compruebo si hay camara
if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
try{
//obtengo las instancia de la camara
this.camera= Camera.open(activeCameraId);
}
//Tratamos si hay error en la camara
catch(Exception e){
Toast.makeText(getContext(), "Error al abrir la camara", Toast.LENGTH_LONG).show();
}
}
//En caso de no haber camara
else{
Toast.makeText(getContext(), "No hay camara", Toast.LENGTH_LONG).show();
}
}
public Camera getCamera(){
return camera;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
//Si la superficie no existe no hago nada
if(holder.getSurface()==null){
return;
}
//detenemos la vista previa de la camara
camera.stopPreview();
//Obtenemos el display, Permite saber si la superficie esta rodada
Display display =((WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
//Obtenemos la rotacion de la cámara
CameraInfo info= new Camera.CameraInfo();
Camera.getCameraInfo(0, info);
int cameraOrientation= info.orientation;
//obtenemos el tamaño de la camara
Size cameraSize = camera.getParameters().getPreviewSize();
//Tratamiento para la vista perpendicular
if((display.getRotation()== Surface.ROTATION_0||display.getRotation()==Surface.ROTATION_180)&&
(cameraOrientation==90||cameraOrientation==270)){
//Intercambio alto y ancho
cameraSize.width=camera.getParameters().getPreviewSize().height;
cameraSize.height=camera.getParameters().getPreviewSize().width;
//Rotacion de la camara
camera.setDisplayOrientation(90);
}
//Calculamos la relación del aspecto de la camara
float ratio = (float) cameraSize.width/(float) cameraSize.height;
//Calculamos el tamaño del ancho en función del alto manteniendo el ratio
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams((int) (height*ratio),height,Gravity.CENTER);
surfaceView.setLayoutParams(params);
//Reiniciamos la vista previa
try{
camera.setPreviewDisplay(holder);
camera.startPreview();
}catch(Exception e){
Log.d("CameraPreview","Error al mostrar la vista previa: "+ e.getMessage());
}
}
@Override
//Se crea la superficie en la vista previa de la camara
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try{
camera.setPreviewDisplay(holder);
camera.startPreview();
}catch (IOException e){
Log.d("CameraPreview", "Error al poner la vista previa de la camare" + e.getMessage());
}
}
@Override
//Se destruye la superficie libero la camara y el escuchador
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera= null;
holder.removeCallback(this);
}
马 创建叠加图像
public class Marco extends View{
Paint paint = new Paint();
public Marco(Context context) {
super(context);
}
@Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(50);
canvas.drawRect(getLeft(), getTop(), getRight(), getBottom(), paint);
}
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.integracion.camaratakephoto.CameraPreview
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"/>
<View
class="com.integracion.camaratakephoto.Marco"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"/>
<Button
android:id="@+id/buttonTakePhoto"
android:onClick="takePhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@android:drawable/ic_menu_camera"/>
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
答案 0 :(得分:1)
您有两种选择:
1 - 尝试创建画布,将您的位图图像作为背景绘制(您的Marco)。您正在直接修改照片位图。
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), true);
Bitmap mBitmap = scaledBitmap.copy(Bitmap.Config.ARGB_8888, true);
mBitmap = Bitmap.createBitmap(scaledBitmap.getWidth(), scaledBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(mBitmap);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(50);
mCanvas.drawRect(getLeft(), getTop(), getRight(), getBottom(), paint);
2 - 您可以使用透明背景位图创建画布,绘制并覆盖两个位图
// transparent bitmap background with your bitmap width and height
Bitmap mBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(mBitmap);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(50);
mCanvas.drawRect(getLeft(), getTop(), getRight(), getBottom(), paint);
public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2)
{
try
{
int maxWidth = (bmp1.getWidth() > bmp2.getWidth() ? bmp1.getWidth() : bmp2.getWidth());
int maxHeight = (bmp1.getHeight() > bmp2.getHeight() ? bmp1.getHeight() : bmp2.getHeight());
Bitmap bmOverlay = Bitmap.createBitmap(maxWidth, maxHeight, bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0, 0, null);
canvas.drawBitmap(bmp2, 0, 0, null);
return bmOverlay;
} catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
return null;
}
}