相机视图 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相机更改为人像?