保存叠加图像+ cameraPreview

时间:2014-02-19 10:20:53

标签: android image camera save overlay

我需要在拍照时保存叠加图像,叠加是其他类视图并添加到相机预览中,这是我的代码

主要活动

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"/>        

1 个答案:

答案 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;
 }
}