用相机拍照并获取位图

时间:2014-05-28 20:22:09

标签: android bitmap camera

我正在开发一款Android应用,它使用前置摄像头为用户模拟镜像。我需要应用程序每隔5秒拍一张照片作为位图(自动且无需用户交互),然后我将其与另一个位图结合使用。

对我来说困难的部分:如何拍照并将其作为位图?

我尝试了几种解决方案,但还没有一种解决方案。

另一个标记为重复的问题是手动而不是自动执行此操作。

3 个答案:

答案 0 :(得分:7)

我使用以下代码在布局背景中显示实时相机输入,该按钮将图像保存为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”活动标签中,以确保您的活动始终处于横向,因为除非您更改代码,否则将手机保持在protrait(直立),这将反转图像的方面比例并严重扭曲它。

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

在我的应用程序中,我希望图像捕获布局的每个视图,而不仅仅是像这样的相机Feed: enter image description here

我在此处发布的测试代码隐藏了捕获按钮,因此它不会出现在您的照片中。如果你的应用程序中有更多的视图,并且它们不会在照片中显示,则在捕获时隐藏它们(请参阅代码以了解隐藏的位置)或编辑代码。

------&gt;总结我的帖子这段代码可以做基本的捕捉和保存jpeg,但如果你想要专业的图像,你需要稍微编辑一下。祝你好运:)&lt; ------

答案 1 :(得分:1)

我不知道这个解决方案是否符合您的要求。然而,将图片作为位图拍摄的基础应该是这样的:

 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
    }  
} 

不要忘记在Manifest中设置相机权限:

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

答案 2 :(得分:-1)

您应首先使用IMAGE_CAPTURE Intent

拍摄照片

然后,您需要创建一个临时文件来存储照片,这样就不会使用手机上的所有内存。

之后,使用android.provider.MediaStore.Images.Media.getBitmap()获取位图并选择临时文件。

以下是有关如何执行此操作的完整代码示例:

Android Camera Intent: how to get full sized photo?