利用SurfaceView预览,拍照且保存至相册
发布日期:2021-06-30 11:22:31 浏览次数:2 分类:技术文章

本文共 6509 字,大约阅读时间需要 21 分钟。

mainActivity如下:

package c.c;import java.io.IOException;import java.util.Iterator;import java.util.List;import android.app.Activity;import android.content.ContentResolver;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.graphics.PixelFormat;import android.hardware.Camera;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.os.Bundle;import android.provider.MediaStore;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.View.OnClickListener;import android.widget.RelativeLayout;/** *需求描述: *利用SurfaceView预览,且拍照. *将拍摄后的图片保存至相册 * *注意 *1 权限 *  
*2 屏幕旋转后SurfaceView中预览的图片有90度的旋转 * 解决方式: * 2.1将屏幕设置为竖屏 * setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); * 2.2设置相机的Orientation * mCamera.setDisplayOrientation(90); * 注意: * 该问题虽然解决了,但是会带来以下的一个问题. *3 拍照保存的图片可能被旋转90度. * 解决方式: * http://blog.csdn.net/walker02/article/details/8211628 * http://www.cnblogs.com/andgoo/archive/2012/08/29/2661896.html * * 此Demo中如下解决该问题 * * 关于以上问题解决的说明: * 1 相机拍照默认的是横屏的 * 以ME525+为例,默认的是LOGO在左边 * 平常的竖屏LOGO在上边.所以,需要将相机旋转90度. * 即mCamera.setDisplayOrientation(90); * 这样才能在横竖屏切换后预览画面正常显示. * 2 最好不要在代码中设置Activity以什么方式(横/竖屏)显示,比如: * setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); * 应该写在配置文件中,这样效率更高. * 3 现在已经把Activity设置为竖屏了.所以onConfigurationChanged() * 方法已经不能起到期望的作用. * 但是还需要监听现在屏幕是横屏还是竖屏.所以在此采用了重力感应的 * 方式来实现.应该还有其他更好的办法,待调查. * 4 小bug:LOGO朝右边的时候,拍出的照片仍然被旋转了 */public class MainActivity extends Activity implements SurfaceHolder.Callback,OnClickListener,Camera.PictureCallback{ private SensorManager mSensorManager; private AccSensorListener mAccSensorListener=null; private Sensor mSensor; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private Camera mCamera; private float y=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置Activity竖屏显示 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setContentView(R.layout.main); init(); } private void init(){ mSensorManager=(SensorManager) getSystemService(SENSOR_SERVICE); mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener (new AccSensorListener(), mSensor, SensorManager.SENSOR_DELAY_NORMAL); mAccSensorListener=new AccSensorListener(); mSurfaceView=(SurfaceView) findViewById(R.id.surfaceView); mSurfaceView.setFocusable(true); mSurfaceView.setFocusableInTouchMode(true); mSurfaceView.setClickable(true); mSurfaceView.setOnClickListener(this); mSurfaceHolder=mSurfaceView.getHolder(); //设置该SurfaceView是一个"推送"类型的SurfaceView mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mSurfaceHolder.addCallback(this); } @Override protected void onDestroy() { super.onDestroy(); //取消重力感应 mSensorManager.unregisterListener(mAccSensorListener); } private class AccSensorListener implements SensorEventListener{ public void onSensorChanged(SensorEvent event) { //System.out.println("xxxxxx event.values[1]="+event.values[1]); y=event.values[1]; } public void onAccuracyChanged(Sensor sensor, int accuracy) { } } //2 parameters.getSupportedXXX的到相机支持的一些效果或者模式,比如: //parameters.getSupportedPictureFormats(); //parameters.getSupportedColorEffects(); //parameters.getSupportedFocusModes(); //parameters.getSupportedWhiteBalance(); public void surfaceCreated(SurfaceHolder holder) { final int LARGEST_WIDTH=200; final int LARGEST_HEIGHT=200; int bestWidth=0; int bestHeight=0; mCamera=Camera.open(); Camera.Parameters parameters=mCamera.getParameters(); //操作1 为相机设置某种特效 List
colorEffects=parameters.getSupportedColorEffects(); Iterator
iterator1=colorEffects.iterator(); while (iterator1.hasNext()) { String effect = (String) iterator1.next(); if (effect.equals(Camera.Parameters.EFFECT_SOLARIZE)) { //若支持过度曝光效果,则设置该效果 //parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE); break; } } //操作2 改变SurfaceView的大小 List
previewSizes=parameters.getSupportedPreviewSizes(); if (previewSizes.size()>1) { Iterator
iterator2=previewSizes.iterator(); while (iterator2.hasNext()) { Camera.Size size = (Camera.Size) iterator2.next(); if (size.width>bestWidth&&size.width<=LARGEST_WIDTH&& size.height>bestHeight&&size.height<=LARGEST_HEIGHT) { bestWidth=size.width; bestHeight=size.height; } } if (bestWidth!=0&&bestHeight!=0) { parameters.setPreviewSize(bestWidth, bestHeight); mSurfaceView.setLayoutParams (new RelativeLayout.LayoutParams(bestWidth, bestHeight)); } } //操作3 当屏幕变化时,旋转角度.否则不对 //因为刚开始时竖屏的 mCamera.setDisplayOrientation(90); //操作结束 try { //将摄像头的预览显示设置为mSurfaceHolder mCamera.setPreviewDisplay(mSurfaceHolder); } catch (IOException e) { mCamera.release(); } //设置输出格式 parameters.setPictureFormat(PixelFormat.JPEG); //设置摄像头的参数.否则前面的设置无效 mCamera.setParameters(parameters); //摄像头开始预览 mCamera.startPreview(); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mCamera.startPreview(); } public void surfaceDestroyed(SurfaceHolder holder) { mCamera.stopPreview(); mCamera.release(); } //处理SurfaceView的点击事件 public void onClick(View v) { mCamera.takePicture(null, null, this); } public void onPictureTaken(byte[] data, Camera camera) { //将图片保存至相册 if (y>0) { System.out.println("竖屏 竖屏 竖屏 竖屏 竖屏 竖屏 "); ContentResolver resolver = getContentResolver(); Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Matrix matrix=new Matrix(); matrix.setRotate(90); Bitmap bitmap2=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); MediaStore.Images.Media.insertImage(resolver, bitmap2, "xxoo", "des"); }else { System.out.println("横屏 横屏 横屏 横屏 横屏 横屏 "); ContentResolver resolver = getContentResolver(); Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); MediaStore.Images.Media.insertImage(resolver, bitmap, "xxoo", "des"); } //mSensorManager.unregisterListener(mAccSensorListener); //拍照后重新开始预览 camera.startPreview(); }}

 

 

main.xml如下:

 

转载地址:https://it9527.blog.csdn.net/article/details/8504650 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:自定义TextView实现跑马灯效果
下一篇:PDF转Word实用工具——ABBYY FineReader

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月26日 05时55分11秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章