2011-07-26 9 views
3

私は画像を描くために使用されているSurfaceViewを持っていて、それらを電話のカメラからのライブフィードにオーバーレイしたいと思います。私はあなたがそれを実行する場合は、プレビューSurfaceView上の画像を1を見ることができるOverlay images onto camera preview surfaceviewhow to draw an overlay on a surfaceview used by camera on android画像をカメラプレビューSurfaceViewにオーバーレイし、保存する方法は?

public class TestCameraOverlayActivity extends Activity { 
     Bitmap bitmap; 

     /** Called when the activity is first created. */ 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       requestWindowFeature(Window.FEATURE_NO_TITLE); 
       Preview mPreview = new Preview(this); 
       DrawOnTop mDraw = new DrawOnTop(this); 
       bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon); 
       setContentView(mPreview); 
       addContentView(mDraw, new LayoutParams (LayoutParams.WRAP_CONTENT, 
       LayoutParams.WRAP_CONTENT)); 
     } 

     class DrawOnTop extends View { 
      public DrawOnTop(Context context) { 
       super(context); 

     } 

     @Override 
     protected void onDraw(Canvas canvas) { 
      Paint paint = new Paint(); 
      paint.setStyle(Paint.Style.STROKE); 
      paint.setColor(Color.BLACK); 
      canvas.drawText("Test Text", 10, 10, paint); 
      canvas.drawBitmap(bitmap, 0, 0, null); 
      super.onDraw(canvas); 
     } 
    } 

    class Preview extends SurfaceView implements SurfaceHolder.Callback { 
     SurfaceHolder mHolder; 
     Camera mCamera; 

     Preview(Context context) { 
      super(context); 
      // Install a SurfaceHolder.Callback so we get notified when the 
      // underlying surface is created and destroyed. 
      mHolder = getHolder(); 
      mHolder.addCallback(this); 
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     } 

     public void surfaceCreated(SurfaceHolder holder) { 
      // The Surface has been created, acquire the camera and tell it where 
      // to draw. 
      mCamera = Camera.open(); 
      try { 
     mCamera.setPreviewDisplay(holder); 
     } catch (IOException e) { 

      e.printStackTrace(); 
     } 
     } 

     public void surfaceDestroyed(SurfaceHolder holder) { 
      // Surface will be destroyed when we return, so stop the preview. 
      // Because the CameraDevice object is not a shared resource, it's very 
      // important to release it when the activity is paused. 
      mCamera.stopPreview(); 
      mCamera = null; 
     } 

     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
      // Now that the size is known, set up the camera parameters and begin 
      // the preview. 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setPreviewSize(w, h); 
      mCamera.setParameters(parameters); 
      mCamera.startPreview(); 
     } 
    } 
} 

を読みましたが、私の質問には、SDカードにJPEGとしてそれらを一緒に保存する方法です。フォーマット変換が必要な場合は、私は同時にそれらを保存することができますいくつかのアドバイスを与えることができますか?イメージを保存する私の部分的な解決

/** Handles data for jpeg picture */ 
PictureCallback jpegCallback = new PictureCallback() { 

public void onPictureTaken(byte[] data, Camera camera) { 
    FileOutputStream outStream = null; 
try { 
    // write to local sandbox file system 
     // outStream = CameraDemo.this.openFileOutput(String.format("%d.jpg", 
      System.currentTimeMillis()), 0); 

     // Or write to sdcard 
    outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", 
     System.currentTimeMillis())); 
    outStream.write(data); 
    outStream.close(); 
    Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length); 
} catch (FileNotFoundException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} finally { 
} 
Log.d(TAG, "onPictureTaken - jpeg"); 
} 
}; 

答えて

4

私はあなたが2つのイメージを1つにマージする方法を尋ねていると思います。

まず、AsynchHandlerを使用してイメージを保存して、UIをロックしないようにします。これは問題の一部ではありませんが、そうなります。

一般的な質問については、asked and answered hereでした。一般に、2つの画像部分を結合し、オーバーレイ全体またはコンポーネント画像部分のスケーリングを処理する必要があります。

4

私はこの写真に基づいて次のサンプルコードを作成し、写真をタックしてオーバーレイ画像とマージし、最後の画像を/ sdcard/DCIM/CameraAPIDemoに保存しました。

また、ここで見つけることができるシンプルなアプリと統合されています。 https://github.com/jiahaoliuliu/RealMadridvsBorussia

package com.jiahaoliuliu.android.futbol.realmadridvsborussia; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.text.SimpleDateFormat; 
import java.util.Date; 

import android.net.Uri; 
import android.os.Bundle; 
import android.os.Environment; 
import android.provider.MediaStore; 
import android.renderscript.ProgramVertexFixedFunction.Constants; 
import android.app.ActionBar.LayoutParams; 
import android.app.Activity; 
import android.content.Context; 
import android.content.Intent; 
import android.content.pm.ActivityInfo; 
import android.content.res.Resources; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.CompressFormat; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.hardware.Camera; 
import android.hardware.Camera.PictureCallback; 
import android.util.Log; 
import android.view.Menu; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.Window; 
import android.widget.Button; 
import android.widget.FrameLayout; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

public class PreviewCamera extends Activity implements OnClickListener{ 

    private static final String LOG_TAG = PreviewCamera.class.getSimpleName(); 
    private Bitmap bitmap; 
    private Preview mPreview; 
    private Long topPhotoLong; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      requestWindowFeature(Window.FEATURE_NO_TITLE); 

      // Get the intent 
      Intent startedIntent = getIntent(); 

      // Get the team 
      topPhotoLong = startedIntent.getLongExtra(PhotoGallery.TOP_PHOTO_ID_NAME, new Long(-1)); 

      if (topPhotoLong > -1) { 
       Log.v(LOG_TAG, "The photoId is " + topPhotoLong); 
       bitmap = BitmapFactory.decodeResource(getResources(), topPhotoLong.intValue()); 

      } else { 
       Log.w(LOG_TAG, "Photo id not found"); 
      } 

      FrameLayout Game = new FrameLayout(this); 
      mPreview = new Preview(this); 
      DrawOnTop mDraw = new DrawOnTop(this); 
      LinearLayout GameWidgets = new LinearLayout (this); 

      Button EndGameButton = new Button(this); 
      TextView MyText = new TextView(this); 

      EndGameButton.setWidth(1200); 
      EndGameButton.setText("Take photo"); 

      GameWidgets.addView(EndGameButton); 

      Game.addView(mPreview); 
      Game.addView(GameWidgets); 

      setContentView(Game); 
      addContentView(mDraw, new LayoutParams (LayoutParams.WRAP_CONTENT, 
      LayoutParams.WRAP_CONTENT)); 

      EndGameButton.setOnClickListener(this); 
      // Lock the screen to landscape 
      this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

    } 

    class DrawOnTop extends View { 
     public DrawOnTop(Context context) { 
      super(context); 

    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     if (bitmap != null) { 
      canvas.drawBitmap(bitmap, 0, 0, null); 
     } 
     super.onDraw(canvas); 
    } 
} 

    public void onClick(View v) { 
     Log.v(LOG_TAG, "Taking picture"); 
     mPreview.takePicture(); 
    } 

class Preview extends SurfaceView implements SurfaceHolder.Callback { 
    SurfaceHolder mHolder; 
    Camera mCamera; 

    Preview(Context context) { 
     super(context); 
     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, acquire the camera and tell it where 
     // to draw. 
     mCamera = Camera.open(); 
     try { 
      mCamera.setPreviewDisplay(holder); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // Surface will be destroyed when we return, so stop the preview. 
     // Because the CameraDevice object is not a shared resource, it's very 
     // important to release it when the activity is paused. 
     mCamera.stopPreview(); 
     mCamera = null; 
    } 

    public void takePicture() { 
     mCamera.takePicture(null, null, new PhotoHandler(getApplicationContext())); 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     // Now that the size is known, set up the camera parameters and begin 
     // the preview. 
     Camera.Parameters parameters = mCamera.getParameters(); 
     parameters.setPreviewSize(w, h); 
     //mCamera.setParameters(parameters); 
     mCamera.startPreview(); 
    } 
} 
public class PhotoHandler implements PictureCallback { 

    private final Context context; 

    public PhotoHandler(Context context) { 
     this.context = context; 
    } 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 

     File sdDir = Environment 
       .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); 

     File pictureFileDir = new File(sdDir, "/CameraAPIDemo"); 

     if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) { 

      Log.d(LOG_TAG, "Can't create directory to save image."); 
      Toast.makeText(context, "Can't create directory to save image.", 
        Toast.LENGTH_LONG).show(); 
      return; 

     } 

     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss"); 
     String date = dateFormat.format(new Date()); 
     String photoFile = "Picture_" + date + ".jpg"; 

     String filename = pictureFileDir.getPath() + File.separator + photoFile; 

     File pictureFile = new File(filename); 

     try { 
      FileOutputStream fos = new FileOutputStream(pictureFile); 
      fos.write(data); 
      fos.close(); 
      Toast.makeText(context, "New Image saved:" + photoFile, 
        Toast.LENGTH_LONG).show(); 

      // TODO: Merge the photo 
      try { 
       Bitmap bottomImage = BitmapFactory.decodeFile(pictureFile.getAbsolutePath()); //blue 

       bitmap = Bitmap.createBitmap(bottomImage.getWidth(), bottomImage.getHeight(), Bitmap.Config.ARGB_8888); 
       Canvas c = new Canvas(bitmap); 
       Resources res = getResources(); 

       Bitmap topImage = BitmapFactory.decodeResource(res, topPhotoLong.intValue()); //green 
       Drawable drawable1 = new BitmapDrawable(bottomImage); 
       Drawable drawable2 = new BitmapDrawable(topImage); 


       drawable1.setBounds(0, 0, bottomImage.getWidth(), bottomImage.getHeight()); 
       drawable2.setBounds(0, 0, bottomImage.getWidth(), bottomImage.getHeight()); 
       drawable1.draw(c); 
       drawable2.draw(c); 


      } catch (Exception e) { 
      } 
      // To write the file out to the SDCard: 
      OutputStream os = null; 
      try { 
       os = new FileOutputStream(filename); 
       bitmap.compress(Bitmap.CompressFormat.PNG, 50, os); 
      } catch(IOException e) { 
       e.printStackTrace(); 
      } 
     } catch (Exception error) { 
      Log.d(LOG_TAG, "File" + filename + "not saved: " 
        + error.getMessage()); 
      Toast.makeText(context, "Image could not be saved.", 
        Toast.LENGTH_LONG).show(); 
     } 
    } 

} 
} 
関連する問題