相机视图 SurfaceView 仅以横向存储

Posted

技术标签:

【中文标题】相机视图 SurfaceView 仅以横向存储【英文标题】:Camera View SurfaceView Stored in Landscape only 【发布时间】:2016-07-06 04:57:08 【问题描述】:

我在 android 中尝试使用相机并想到使用surfaceview 的overrelay 帧,找到了这个例子..Android creating camera and overrelay frame。例子很棒。

1.开始增强所以改变了肖像和风景框架,当我更改为肖像时相机视图没有显示所以检查并从这个链接***(changing display orientation)得到答案,表面中插入的代码改变了..显示错误setparameters,所以删除,它工作了

2.但是当我看到我拍的照片时,它是这样显示的..Image.然后再次从这个链接ExifInterface(orientatioin)得到ans@

    前置摄像头也没有打开.. ??

cambutton.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<ImageButton
android:id="@+id/btnCapture"
android:layout_
android:layout_
android:layout_marginTop="500dp"
android:background="@drawable/cam"
android:layout_centerHorizontal="true"
/>
<ImageButton
    android:id="@+id/btnswitch"
    android:layout_
    android:layout_
    android:background="@drawable/switchcamera"
    android:layout_marginLeft="85dp"
    android:layout_marginStart="85dp"
    android:layout_marginTop="500dp"
    android:layout_toRightOf="@id/btnCapture"
    android:layout_toEndOf="@id/btnCapture"
    />

</RelativeLayout>

campotrait.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
>

<SurfaceView
    android:id="@+id/cameraSurfaceView"
    android:layout_
    android:layout_
    android:background="@drawable/frame3"
    />
</LinearLayout>

camoverrelay1.xml 是横向的,上面的代码相同

Share.java

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;


public class Share extends Activity implements SurfaceHolder.Callback

private Camera camera = null;
private SurfaceView cameraSurfaceView = null;
private SurfaceHolder cameraSurfaceHolder = null;
private boolean previewing = false;

private Display display = null;

private static int wid = 0, hgt = 0;

private LayoutInflater layoutInflater = null;
private View cameraViewControl = null;
private RelativeLayout.LayoutParams layoutParamsControl = null;

private ImageButton btnCapture = null;
private ImageButton btnswitch = null;
Camera.Size previewSize=null;
Camera.Size optimalSize = null;
Bitmap mBitmap;
@Override
protected void onCreate(Bundle savedInstanceState)

    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    display = getWindowManager().getDefaultDisplay();
    wid = display.getWidth();
    hgt = display.getHeight();

    getWindow().setFormat(PixelFormat.TRANSLUCENT);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
 getWindow().setFlags(WindowManager.LayoutParams.
  FLAG_FULLSCREEN,   WindowManager.
  LayoutParams.FLAG_FULLSCREEN);
    int orientation = getResources().getConfiguration().orientation;
  /*  Camera.Parameters p = camera.getParameters();
    p.set("orientation", "portrait");
    p.set("rotation", 90);
    camera.setParameters(p);*/
    if ((orientation == Configuration.ORIENTATION_PORTRAIT)) 
     /*   camera.setDisplayOrientation(90);*/
        setContentView(R.layout.campotrait);
    
    else
       /* camera.setDisplayOrientation(180);*/
        setContentView(R.layout.cameraoverlay1);
    

    cameraSurfaceView = (SurfaceView)findViewById(R.id.cameraSurfaceView);
    cameraSurfaceHolder = cameraSurfaceView.getHolder();
    cameraSurfaceHolder.addCallback(this);
    cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    layoutInflater = LayoutInflater.from(getBaseContext());
    layoutParamsControl = new RelativeLayout.LayoutParams
 (RelativeLayout.LayoutParams.FILL_PARENT,RelativeLayout.LayoutParams.
 FILL_PARENT);

    cameraViewControl = layoutInflater.inflate(R.layout.cambutton, null);
    this.addContentView(cameraViewControl, layoutParamsControl);
    btnCapture = (ImageButton)findViewById(R.id.btnCapture);
    btnswitch = (ImageButton) findViewById(R.id.btnswitch);
    btnCapture.setOnClickListener(new View.OnClickListener()
    
        @Override
        public void onClick(View v)
        
            // TODO Auto-generated method stub
            camera.takePicture(cameraShutterCallback,
                    cameraPictureCallbackRaw,
                    cameraPictureCallbackJpeg);

        
    );
    btnswitch.setOnClickListener(new View.OnClickListener()
    
        @Override
        public void onClick(View v)
        
            // TODO Auto-generated method stub
            int camerasNumber = Camera.getNumberOfCameras();
            if (camerasNumber > 1) 
                //release the old camera instance
                //switch camera, from the front and the back and vice versa
                openFrontFacingCameraGingerbread();
             else 
 Toast toast = Toast.makeText(getApplicationContext(),  "Sorry, your 
 phone has only one camera!", Toast.LENGTH_LONG);
                toast.show();
            
        
    );
 
 private Camera openFrontFacingCameraGingerbread() 
    int cameraCount = 0;
    Camera cam = null;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) 
        Camera.getCameraInfo(camIdx, cameraInfo);
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) 
            try 
                cam = Camera.open(camIdx);
             catch (RuntimeException e) 
                e.printStackTrace();
 Toast.makeText(getApplicationContext(),"Failed to Open 
  Front Camera",Toast.LENGTH_SHORT).show();
            
        
    

    return cam;
 
Camera.ShutterCallback cameraShutterCallback = new Camera.ShutterCallback()

    @Override
    public void onShutter()
    

    
 ;

 Camera.PictureCallback cameraPictureCallbackRaw = 
 new Camera.PictureCallback()

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

    
;

Camera.PictureCallback cameraPictureCallbackJpeg = 
new Camera.PictureCallback()

    @Override
    public void onPictureTaken(byte[] data, Camera camera)
    
        // TODO Auto-generated method stub
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

        wid =cameraBitmap.getWidth();
        hgt = cameraBitmap.getHeight();


Bitmap newImage = Bitmap.createBitmap(wid,hgt, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(newImage);
        canvas.drawBitmap(cameraBitmap, 0f, 0f, null);
        int orientation = getResources().getConfiguration().orientation;

        if ((orientation == Configuration.ORIENTATION_PORTRAIT))
            Drawable drawable = getResources().getDrawable
                    (R.drawable.potraitimage);
            assert drawable != null;
            drawable.setBounds(0, 0, wid,hgt);
            drawable.draw(canvas);

        
        else
            Drawable drawable = getResources().getDrawable
                    (R.drawable.curtain);
            assert drawable != null;
            drawable.setBounds(0, 0, wid,hgt);
            drawable.draw(canvas);

        
     /*   Bitmap bitm = null;*/
        File storagePath = new File(Environment.
                getExternalStorageDirectory() + "/ActEventz/");
        storagePath.mkdirs();

        File myImage = new File(storagePath, "test.jpg");
 ExifInterface exif;
        try 
            exif = new ExifInterface(storagePath + "test.jpg");
            int orient = exif.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION, 0);
            Log.d("EXIF", "Exif: " + orient);
            Matrix matrix = new Matrix();
            if (orient == 0) 
                matrix.postRotate(0);
                Log.d("EXIF", "Exif: " + orient);
             else if (orient == 90) 
                matrix.postRotate(0);
                Log.d("EXIF", "Exif: " + orient);
            
            mBitmap= Bitmap.createBitmap(cameraBitmap, 0, 
   0,cameraBitmap.getWidth(), cameraBitmap.getHeight(), matrix, true);
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
         mBitmap.compress(Bitmap.CompressFormat.PNG, 0, stream);
        byte[] byteArray= stream.toByteArray();
        Intent i = new Intent(getApplicationContext(), Imageview.class);
        Bundle bu = new Bundle();
        bu.putByteArray("photo",byteArray );
        i.putExtras(bu);
        startActivity(i);
        try
        
            FileOutputStream out = new FileOutputStream(myImage);
            newImage.compress(Bitmap.CompressFormat.JPEG, 80, out);
   Toast.makeText(getApplicationContext(), "Image Captured",
   Toast.LENGTH_SHORT).show();
            out.flush();
            out.close();
         catch(IOException e)
        
            Log.d("In Saving File", e + "");
        
      /*  Matrix matrix = new Matrix();
        matrix.postRotate(90);
        Bitmap bitmap = BitmapFactory.decodeFile(storagePath+"test.jpg");
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(),bitmap.getHeight(), matrix, true);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 
 hgt,wid,true);

        scaledBitmap.compress(Bitmap.CompressFormat.PNG, 0, stream);*/

        camera.startPreview();  
        newImage.recycle();
        newImage = null;
        cameraBitmap.recycle();
        cameraBitmap = null;
    
;
@Override
public void onRequestPermissionsResult(int requestCode, 
String permissions[], int[] grantResults) 
    switch (requestCode) 
        case 200: 
            // If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] ==PackageManager.
 PERMISSION_GRANTED) 
                //Permission Granted
             else 
                //Permission Denied
            
            return;
  //Use other case lines for other requests (with different requestCodes)
        
    
 
 @Override
 public void surfaceChanged(SurfaceHolder holder,
                           int format, int width, int height)
 
    // TODO Auto-generated method stub

    if(previewing)
    
        camera.stopPreview();
        previewing = false;
    

        Camera.Parameters parameters = camera.getParameters();
 Display display = ((WindowManager)getSystemService
 (WINDOW_SERVICE)).getDefaultDisplay();
 List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
         previewSize=previewSizes.get(0);

     // You need to choose the most appropriate previewSize for your app
     // .... select one of previewSizes here
 /* parameters.setPreviewSize(previewSize.width, previewSize.height);*/
       if(display.getRotation() == Surface.ROTATION_0)
        
            parameters.setPreviewSize(previewSize.height,previewSize.width);
            camera.setDisplayOrientation(90);

        

        if(display.getRotation() == Surface.ROTATION_90)
        
            parameters.setPreviewSize(previewSize.width,previewSize.height);

        

        if(display.getRotation() == Surface.ROTATION_180)
        
            parameters.setPreviewSize(previewSize.height,previewSize.width);
        

        if(display.getRotation() == Surface.ROTATION_270)
        
            parameters.setPreviewSize(previewSize.width,previewSize.height);
            camera.setDisplayOrientation(180);

        
       /*camera.setParameters(parameters);*/
    //here error occurs setParameters failed 
    try
    
            camera.setPreviewDisplay(cameraSurfaceHolder);
            camera.startPreview();
            previewing = true;
        
        catch (IOException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
  
@Override
public void surfaceCreated(SurfaceHolder holder)

    // TODO Auto-generated method stub
    try
    
        camera = Camera.open();
    
    catch(Exception e)
    
 Toast.makeText(getApplicationContext(), "Device camera is not 
working properly, please try after sometime.", Toast.LENGTH_LONG).show();
    


@Override
public void surfaceDestroyed(SurfaceHolder holder)

    // TODO Auto-generated method stub
    camera.stopPreview();
    camera.release();
    camera = null;
    previewing = false;


我已经搜索了很多网站,***,我无法得到正确的答案,唯一的错误是相机的捕获视图请建议我解决方案。我整天都被困在这个问题上。提前谢谢你。

【问题讨论】:

你能不能也分享一下layout xml 嗨 Jickson 我已经添加了 xml 文件.. 我也添加了 exif,然后也显示了相同的风景图像.. 您不需要 EXIF 信息来检查您的图片是否为纵向,并将其旋转 90° 好的,亚历克斯.. 谢谢 【参考方案1】:

感谢支持人员.. 我通过更改 Surface Changed 中的一些代码解决了这个问题.. 我已经删除了 ExifInterface 部分本身.. 刚刚在 SurfaceChanged 中完成下面的编码,图像按预期保存.. :)

@Override
public void surfaceChanged(SurfaceHolder holder,
                   int format, int width, int height)

// TODO Auto-generated method stub

if(previewing)

camera.stopPreview();
previewing = false;

Camera.Parameters parameters = camera.getParameters();
  Display display =   ((WindowManager)getSystemService(WINDOW_SERVICE)).
 getDefaultDisplay();
 int or=cameraInfo.orientation;
 // You need to choose the most appropriate previewSize for your app
// .... select one of previewSizes here
 /* parameters.setPreviewSize(previewSize.width,    previewSize.height);*/
if(display.getRotation() == Surface.ROTATION_0)
 

camera.setDisplayOrientation(90);
or=90;


if(display.getRotation() == Surface.ROTATION_180)

    camera.setDisplayOrientation(270);
or=270;

if(display.getRotation() == Surface.ROTATION_270)

    camera.setDisplayOrientation(180);
    or=180;


parameters.setRotation(or);

 camera.setParameters(parameters);
try

    camera.setPreviewDisplay(cameraSurfaceHolder);
    camera.startPreview();
    previewing = true;

catch (IOException e)

    // TODO Auto-generated catch block
    e.printStackTrace();


【讨论】:

以上是关于相机视图 SurfaceView 仅以横向存储的主要内容,如果未能解决你的问题,请参考以下文章

如何在surfaceview中将Android相机更改为人像?

相机表面视图图像看起来拉伸

android自定义相机拉伸surfaceview

如何在 SurfaceView Android 上制作裁剪相机视图

捕获显示横向方向的 UIimage 视图中存储的图像

android - 使用没有surfaceview或textureview的相机