web-dev-qa-db-ja.com

カメラで写真を撮ってビットマップを取得する

私はAndroid用のアプリを開発しています。これは、正面カメラを使用してユーザーの鏡をシミュレートします。アプリは5秒ごとにビットマップとして写真を撮る必要があります(自動的にユーザーなしで)相互作用)、それを後で別のビットマップと組み合わせます。

私にとっての難しい部分:写真を撮ってビットマップとして取得する方法は?

私はいくつかの解決策を試しましたが、どれもまだ機能していません。

これがの重複としてマークされているというもう1つの質問は、これを手動ではなく自動で行うことです。

13
moobi

次のコードを使用して、レイアウトの背景にライブカメラフィードを表示し、ボタンで画像をjpegとして保存しました。試してみて、必要に応じて変更してください。テストプロジェクト全体をここからダウンロードして、すばやくテストできます。 http://www.4shared.com/rar/v-ZQPybcce/Test.html

--- >>このコードとインテントを使用する他のコードとの違いは、カメラアプリを開かなくても自動的に写真が撮られるため、アプリの見栄えがよくなることです:) <----

package com.mreprogramming.test;

import Java.io.ByteArrayInputStream;
import Java.io.ByteArrayOutputStream;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Android.view.SurfaceHolder;
import Android.view.SurfaceView;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.widget.Button;
import Android.widget.ImageView;
import Android.widget.RelativeLayout;
import Android.widget.Toast;
import Android.app.Activity;
import Android.content.Context;
import Android.content.SharedPreferences;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.graphics.Bitmap.CompressFormat;
import Android.hardware.Camera;
import Android.hardware.Camera.PictureCallback;
import Android.os.Bundle;
import Android.os.Environment;
import Android.preference.PreferenceManager;


public class CameraActivity extends Activity implements SurfaceHolder.Callback{

    protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
    private SurfaceView SurView;
    private SurfaceHolder camHolder;
    private boolean previewRunning;
    private Button button1;
    final Context context = this;
    public static Camera camera = null;
    private ImageView camera_image;
    private Bitmap bmp,bmp1;
    private ByteArrayOutputStream bos;
    private BitmapFactory.Options options,o,o2;
    private FileInputStream fis;
    ByteArrayInputStream fis2;
    private FileOutputStream fos;
    private File dir_image2,dir_image;
    private RelativeLayout CamView;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera);



    CamView = (RelativeLayout) findViewById(R.id.camview);

    SurView = (SurfaceView)findViewById(R.id.sview);
    camHolder = SurView.getHolder();
    camHolder.addCallback(this);
    camHolder.setType(SurfaceHolder.SURFACE_TYPE_Push_BUFFERS);
    button1 = (Button)findViewById(R.id.button_1);


    camera_image = (ImageView) findViewById(R.id.camera_image);


    button1.setOnClickListener(new OnClickListener()
    {

    public void onClick(View v)
    {

        button1.setClickable(false);
        button1.setVisibility(View.INVISIBLE);  //<-----HIDE HERE 
        camera.takePicture(null, null, mPicture);

    }

    });


    }




    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    if(previewRunning){
        camera.stopPreview();
    }
    Camera.Parameters camParams = camera.getParameters();
    Camera.Size size = camParams.getSupportedPreviewSizes().get(0); 
    camParams.setPreviewSize(size.width, size.height);
    camera.setParameters(camParams);
    try{
        camera.setPreviewDisplay(holder);
        camera.startPreview();
        previewRunning=true;
    }catch(IOException e){
        e.printStackTrace();
    }
    }

    public void surfaceCreated(SurfaceHolder holder) {
    try{
        camera=Camera.open();
    }catch(Exception e){
        e.printStackTrace();
        Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
        finish();
    }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    camera.release();
    camera=null;
    }



    public void TakeScreenshot(){

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        int nu = preferences.getInt("image_num",0);
        nu++;
        SharedPreferences.Editor editor = preferences.edit();
        editor.putInt("image_num",nu);
        editor.commit();
        CamView.setDrawingCacheEnabled(true); 
        CamView.buildDrawingCache(true);
        bmp = Bitmap.createBitmap(CamView.getDrawingCache());
        CamView.setDrawingCacheEnabled(false);
                        bos = new ByteArrayOutputStream(); 
                        bmp.compress(CompressFormat.JPEG, 100, bos); 
                        byte[] bitmapdata = bos.toByteArray();
                        fis2 = new ByteArrayInputStream(bitmapdata);

                        String picId=String.valueOf(nu);
                        String myfile="MyImage"+picId+".jpeg";

                        dir_image = new  File(Environment.getExternalStorageDirectory()+
                                File.separator+"My Custom Folder");
                        dir_image.mkdirs();

                        try {
                            File tmpFile = new File(dir_image,myfile); 
                            fos = new FileOutputStream(tmpFile);

                             byte[] buf = new byte[1024];
                                int len;
                                while ((len = fis2.read(buf)) > 0) {
                                    fos.write(buf, 0, len);
                                }
                                    fis2.close();
                                    fos.close();

                                    Toast.makeText(getApplicationContext(),
                                            "The file is saved at :/My Custom Folder/"+"MyImage"+picId+".jpeg",Toast.LENGTH_LONG).show();

                                    bmp1 = null;
                                    camera_image.setImageBitmap(bmp1);
                                    camera.startPreview();
                                    button1.setClickable(true);
                                          button1.setVisibility(View.VISIBLE);//<----UNHIDE HER
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }


    }

    private PictureCallback mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            dir_image2 = new  File(Environment.getExternalStorageDirectory()+
                    File.separator+"My Custom Folder");
            dir_image2.mkdirs();


            File tmpFile = new File(dir_image2,"TempImage.jpg");
            try {
                fos = new FileOutputStream(tmpFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
                Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
            } catch (IOException e) {
                Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
            }
            options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;

                bmp1 = decodeFile(tmpFile);
                bmp=Bitmap.createScaledBitmap(bmp1,CamView.getWidth(), CamView.getHeight(),true);
                camera_image.setImageBitmap(bmp);
                tmpFile.delete();
                TakeScreenshot();

        }
    };


    public Bitmap decodeFile(File f) {
        Bitmap b = null;
        try {
            // Decode image size
            o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;

            fis = new FileInputStream(f);
            BitmapFactory.decodeStream(fis, null, o);
            fis.close();
            int IMAGE_MAX_SIZE = 1000;
            int scale = 1;
            if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
                scale = (int) Math.pow(
                        2,
                        (int) Math.round(Math.log(IMAGE_MAX_SIZE
                                / (double) Math.max(o.outHeight, o.outWidth))
                                / Math.log(0.5)));
            }

            // Decode with inSampleSize
            o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            fis = new FileInputStream(f);
            b = BitmapFactory.decodeStream(fis, null, o2);
            fis.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

        return b;
    }


}

これはcamera.xmlです

 <RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent" 
Android:id="@+id/camview">

<SurfaceView
Android:id="@+id/sview"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_alignParentLeft="true"
Android:layout_alignParentTop="true" />

<ImageView
    Android:id="@+id/camera_image"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:contentDescription="@string/app_name" />

<Button
    Android:id="@+id/button_1"
    Android:layout_width="20dp"
    Android:layout_height="20dp"
    Android:layout_alignParentLeft="true"
    Android:layout_alignParentTop="true" />

これをマニフェストに追加してください:

<uses-permission Android:name="Android.permission.CAMERA" />
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>

また、マニフェストで "CameraActivity"アクティビティタブに以下を追加して、アクティビティが常に横向きになるようにしてください。そうしないと、コードを変更しない限り、電話を縦(直立)に保つと、画像の縦横比が大きく逆になり、それを歪めます。

<activity
        Android:name="com.mreprogramming.test.CameraActivity"
        Android:label="@string/app_name"
        Android:screenOrientation="landscape" >   <-------ADD THIS ---!!!!!
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

そして、これをstyles.xmlとして保存して、レイアウトをフルスクリーンにします

<resources>

<!--
    Base application theme, dependent on API level. This theme is replaced
    by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="Android:Theme.NoTitleBar.Fullscreen">
    <!--
        Theme customizations available in newer API levels can go in
        res/values-vXX/styles.xml, while customizations related to
        backward-compatibility can go here.
    -->
</style>

<!-- Application theme. -->
<style name="AppTheme" parent="Android:Theme.NoTitleBar.Fullscreen">
    <item name="Android:windowFullscreen">true</item>
    <item name="Android:windowNoTitle">true</item>
</style>

私のアプリでは、次のようなカメラフィードだけでなく、レイアウトのすべてのビューを画像でキャプチャする必要があります。 enter image description here

ここに投稿したテストコードはキャプチャボタンを非表示にして、写真に表示されないようにします。アプリにさらにビューがあり、写真に表示しない場合は、キャプチャ中にビューを非表示にする(非表示にする場所についてはコードを参照)か、コードを編集します。

------>私の投稿を要約すると、このコードはjpegの基本的なキャプチャと保存を行うことができますが、プロの画像が必要な場合は少し編集する必要があります。幸運:)<------

7
mremremre1

この解決策があなたの望むものかどうかはわかりません。ただし、ビットマップとして写真を撮る基本は次のようになります。

 private static final int CAMERA_REQUEST = 1888; // field

 private void takePicture(){ //you can call this every 5 seconds using a timer or whenever you want
  Intent cameraIntent = new  Intent(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
  startActivityForResult(cameraIntent, CAMERA_REQUEST); 
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {  
        Bitmap picture = (Bitmap) data.getExtras().get("data");//this is your bitmap image and now you can do whatever you want with this 
        imageView.setImageBitmap(picture); //for example I put bmp in an ImageView
    }  
} 

マニフェストでカメラの権限を設定することを忘れないでください:

<uses-feature Android:name="Android.hardware.camera" />
2