用相机拍照并获取位图 [英] Take a picture with camera and get bitmap

查看:12
本文介绍了用相机拍照并获取位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款安卓应用,它使用前置摄像头为用户模拟镜子.我需要该应用每 5 秒拍摄一张图片作为位图(自动且无需用户交互),然后我稍后将其与另一个位图合并.

I am working on an app for android that uses the front facing camera to simulate a mirror for the user. I need the app to take a picture every 5 seconds as a bitmap(automatically and without user interaction), which I then combine with another bitmap later on.

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

The difficult part for me: How to take a picture and get it as a bitmap?

我尝试了多种解决方案,但都没有奏效.

I tried several solutions, but none have worked yet.

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

The other question that this is marked as a duplicate for is for doing this manually and not automatically.

推荐答案

我使用以下代码在布局背景中显示实时摄像机源,并且按钮将图像保存为 jpeg.尝试根据需要修改它:您可以在此处下载整个测试项目,以便快速测试:http://www.4shared.com/rar/v-ZQPybcce/Test.html

I used the following code to show live camera feed in a layout background and the button saves the image as jpeg. Try and modify it as you wish : You can download the entire test project here so that you can test it fast : http://www.4shared.com/rar/v-ZQPybcce/Test.html

--->>此代码与其他使用意图的代码的不同之处在于它无需打开相机应用程序即可自动拍照,这使应用程序看起来更好:) <----

--->>The difference of this code from others using intents is that it takes the picture automatically without opening the camera app which makes the app look better :) <----

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

This is the 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" />

将此添加到您的清单中:

Add this to your manifest :

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

还在清单中将以下内容添加到CameraActivity"活动选项卡,以确保您的活动始终处于横向状态,否则将手机保持直立(直立),除非您更改代码,否则它将反转图像的外观比例并严重扭曲.

Also in the manifest add the following to the "CameraActivity" activity tab to make sure that your activity will always be in landscape orientation because otherwise holding the phone in protrait(upright) unless you change the code it will reverse the image's aspect ratio and severely distort it.

<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以使您的布局全屏

And save this as styles.xml to make your layout fullscreen

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

在我的应用程序中,我希望图像捕捉布局的每个视图,而不仅仅是像这样的相机馈送:

In my app i want the image to capture every view of the layout not just the camera feed like this :

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

The test code I posted here hides the capture button so that it wont appear in your photo. If you have more views in your app and don't won't them to show in the photo either hide them while capturing (see code to know where to hide) or edit the code.

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

------>To sum up my post this code can do the basic capturing and saving a jpeg but if you want professional images you need to edit it a bit. Good Luck :)<------

这篇关于用相机拍照并获取位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆