当前位置:  编程技术>移动开发
本页文章导读:
    ▪运用surfaceView制作的拍照demo        使用surfaceView制作的拍照demo 这是一个用surfaceview来捕捉摄像头画面并拍照存储图片到sdcard的demo。众所周知,在一个应用中,我们可以通过intent来调用系统自带的相机功能进行拍 照,但,这样.........
    ▪ 基于Tableview的滚动,如何避免数据不变的有关问题-待整理        基于Tableview的滚动,如何处理数据不变的问题-----待整理http://hi.baidu.com/justtmiss/item/f3f6d50ce395f1d872e67630--感谢这边文章的作者,我从里面得到了启发 http://hi.baidu.com/justtmiss/item/f3f6d50ce395f1d872e67.........
    ▪ 关于手逛数值的一些想法       关于手游数值的一些想法1、先难后易、玩家会接受 如果先易后难 玩家很难接受 2、数值在运营之前一定要设计好 坚决不能改 玩家玩着玩着就习惯了、要不然重要数值改来改去 玩家很容易流.........

[1]运用surfaceView制作的拍照demo
    来源: 互联网  发布时间: 2014-02-18
使用surfaceView制作的拍照demo

这是一个用surfaceview来捕捉摄像头画面并拍照存储图片到sdcard的demo。众所周知,在一个应用中,我们可以通过intent来调用系统自带的相机功能进行拍

照,但,这样做不如自己写一个拍照界面来的酷!用surfaceview的方式来做,你可以随心所欲的设计自己的界面。

在这个例子中,我用代码制作了一个拍摄界面,里面只有三个控件,一个是自己封装的CameraView,它继承了SurfaceView,一个是悬浮在CameraView上的按

钮,点击它可以捕捉画面并把图像存储到sdCard的根目录下,还有一个是悬浮在CameraView上的TextView,它不过显示一行文字而已。

程序运行截图如下:

存储在sdcard根目录下的图片如下:

 

你可以看到,在surfaceview中所呈现的图像和保存的图像是一样的,这样做保证了所见即所得。

代码如下:

这是MainActivity,程序一运行就打开的Activity:

public class MainActivity extends Activity {

	private CameraView mCameraView;
	private Button takePictureBtn;
	private Camera mCamera;
	private Bitmap mBitmap;
	private int bitmapWidth;
	private int bitmapHeight;
	
	private RelativeLayout rl;
	
	// 准备一个保存图片的pictureCallback对象
	public Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
		
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			// TODO Auto-generated method stub
			
			if(camera != null){
				Toast.makeText(getApplicationContext(), "正在保存...", Toast.LENGTH_LONG).show();
				// 用BitmapFactory.decodeByteArray()方法可以把相机传回的裸数据转换成Bitmap对象
				// 这里通过BitmapFactory.Options类指定解码方法
				BitmapFactory.Options options = new BitmapFactory.Options();
				// 在解码图片的时候设置inJustDecodeBounds属性为true,可以避免内存分配
//				options.inJustDecodeBounds = true;	这句话已开启就会死机
				mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
				bitmapWidth = options.outWidth;
				bitmapHeight = options.outHeight;
				// 把bitmap保存成一个存储卡中的文件
				File file = new File("/sdcard/YY"+ new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".png");
				try {
					file.createNewFile();
					BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
					mBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
					os.flush();
					os.close();
					Toast.makeText(getApplicationContext(), "图片 " + bitmapWidth + "X" + bitmapHeight +" 保存完毕,在存储卡的根目录", Toast.LENGTH_LONG).show();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}	
			
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//窗口去掉标题
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		//窗口设置为全屏
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
		//设置窗口为半透明
		getWindow().setFormat(PixelFormat.TRANSLUCENT);
		
		// 创建布局
		rl = new RelativeLayout(this);
		
		// 添加CameraView
		addCameraView(rl);
		// 添加拍摄按钮
		addTakePictureBtn(rl);
		// 添加提示文字
		addTextView(rl);
	    
	    // 设置布局
	    setContentView(rl);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	/**
	 * 添加CamearView
	 * @param rl 所在的布局
	 */
	private void addCameraView(RelativeLayout rl){
		
		// 打开相机
		this.mCamera = Camera.open();
		
		// 设置CameraView的大小和位置
		// 1、首先得到保存在sdcard的图片大小
		Camera.Parameters parameters = this.mCamera.getParameters();
		Size sdCardPictureSize = CameraView.getOptimalPictureSize(parameters.getSupportedPictureSizes(), 640, 480);
		// 2、得到设备的屏幕分辨率
		DisplayMetrics dm = new DisplayMetrics();
	    getWindowManager().getDefaultDisplay().getMetrics(dm);
	    // 3、根据以上两个数据计算出CameraView的大小
	    float scale = (float)dm.heightPixels/(float)sdCardPictureSize.height;
	    int cameraViewWidth = (int) (sdCardPictureSize.width * scale);
	    int cameraViewHeight = (int) (sdCardPictureSize.height * scale);
	    System.out.println("scale: " + scale);
	    System.out.println("cameraView: " + cameraViewWidth + ", " + cameraViewHeight);
	    // 4、把CameraView居中布局
	    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(cameraViewWidth, cameraViewHeight);
	    rlp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
	    // 5、把cameraView添加到rl上
	    this.mCameraView = new CameraView(this);
	    this.mCameraView.setCamera(mCamera);
	    rl.addView(this.mCameraView, rlp);
	}
	
	/**
	 * 添加拍摄按钮
	 * @param rl
	 */
	private void addTakePictureBtn(RelativeLayout rl){
		
		this.takePictureBtn = new Button(this);
		this.takePictureBtn.setText("拍摄");
		this.takePictureBtn.setOnClickListener(new TakePictureBtnOnClickListener());
		// 把按钮放置在屏幕右下角
		RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		rlp.rightMargin = 15;
		rlp.bottomMargin = 15;
		rl.addView(takePictureBtn, rlp);
	}
	
	/**
	 * 添加提示文字
	 * @param rl
	 */
	private void addTextView(RelativeLayout rl){
		
		TextView textView = new TextView(this);
		textView.setText("请点击拍摄按钮拍摄:");
		// 把文字放在屏幕左上角
		RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		rlp.addRule(RelativeLayout.ALIGN_TOP);
		rl.addView(textView, rlp);
	}
	
	
	/**
	 * 拍摄按钮的OnClickListener,在这里执行拍照。
	 * @author haozi
	 *
	 */
	class TakePictureBtnOnClickListener implements View.OnClickListener{

		@Override
		public void onClick(View v) {
			
			if(mCamera != null){
				mCamera.takePicture(null, null, mPictureCallback);
			}else{
				Toast.makeText(getApplicationContext(), "Camera对象为空!", Toast.LENGTH_LONG).show();
			}
		}	
	}
}

这是封装好的CameraView控件,它继承了SurfaceView:

/**
 * 摄像的View
 * @author haozi
 *
 */
public class CameraView extends SurfaceView {

	public Context mContext;
	private SurfaceHolder mSurfaceHolder;
	
	public CameraView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.mContext = context;
	}

	public CameraView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.mContext = context;
	}
	
	public CameraView(Context context) {
		super(context);
		this.mContext = context;
	}
	
	

	/**
	 * 把照相机对象传入
	 * @param mCamera
	 */
	public void setCamera(Camera mCamera){
		
		// 操作surface的holder
		mSurfaceHolder = this.getHolder();
		// 创建surfaceholder对象
		mSurfaceHolder.addCallback(new SurfaceHolderCallback(mCamera));
		// 设置push缓冲类型,说明surface数据由其他来源提供。而不是用自己的Canvas来绘图,在这里由摄像头来提供数据。
		mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}
	
	/**
	 * 得到最适合的预览大小
	 * @param sizes
	 * @param w
	 * @param h
	 * @return
	 */
	public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }
	
	
	/**
	 * 得到最合适的PictureSize
	 * @param sizes
	 * @param w
	 * @param h
	 * @return
	 */
	public static Size getOptimalPictureSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }
	
	/**
	 * 摄像头捕捉到的画面都会在这里被处理
	 * @author haozi
	 *
	 */
	class SurfaceHolderCallback implements SurfaceHolder.Callback{

		private Camera mCamera;
		
		public SurfaceHolderCallback(Camera mCamera){
			
			this.mCamera = mCamera;
		}
		
		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			// TODO Auto-generated method stub
			// 停止预览
			mCamera.stopPreview();
			// 释放相机资源并置空
			mCamera.release();
			mCamera = null;
		}
		
		@Override
		public void surfaceCreated(SurfaceHolder holder) {

			// 设置预览
			try {
				mCamera.setPreviewDisplay(holder);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				// 如果出现异常,释放相机资源并置空
				mCamera.release();
				mCamera = null;
			}
		}
		
		// 当surface视图数据发生变化时,处理预览信息
		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			// TODO Auto-generated method stub
			// 如果相机资源并不为空
			if(mCamera != null){
				
				// 获得相机参数对象
				Camera.Parameters parameters = mCamera.getParameters();
				// 获取最合适的参数,为了做到拍摄的时候所见即所得,我让previewSize和pictureSize相等
				Size previewSize = getOptimalPictureSize(parameters.getSupportedPictureSizes(), 640, 480);
				Size pictureSize = getOptimalPictureSize(parameters.getSupportedPictureSizes(), 640, 480);
				System.out.println("---------------------------");
				System.out.println("previewSize: " + previewSize.width + ", " + previewSize.height);
				System.out.println("pictureSize: " + pictureSize.width + ", " + pictureSize.height);
				// 设置照片格式
				parameters.setPictureFormat(PixelFormat.JPEG);
				// 设置预览大小
				parameters.setPreviewSize(previewSize.width, previewSize.height);
				// 设置自动对焦,先进行判断
				List<String> focusModes = parameters.getSupportedFocusModes();  
				if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {  
					parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
				}	
				// 设置图片保存时候的分辨率大小
				parameters.setPictureSize(pictureSize.width, pictureSize.height);
				// 给相机对象设置刚才设置的参数
				mCamera.setParameters(parameters);
				// 开始预览
				mCamera.startPreview();
			}
		}
	}
}

要使用摄像机,别忘了权限,这是AndroidManifest.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.haozi.demo.screenshot4"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="4"
        android:targetSdkVersion="10" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.haozi.demo.screenshot4.MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
   	<uses-permission android:name="android.permission.CAMERA"/>
   	<uses-permission android:name="android.permission.FLASHLIGHT"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    <uses-feature android:name="android.hardware.camera"/>
    <uses-feature android:name="android.hardware.autofocus"/>
</manifest>

因为是代码布局,所以就没有用到xml布局方式。ok,大功告成!



    
[2] 基于Tableview的滚动,如何避免数据不变的有关问题-待整理
    来源: 互联网  发布时间: 2014-02-18
基于Tableview的滚动,如何处理数据不变的问题-----待整理

http://hi.baidu.com/justtmiss/item/f3f6d50ce395f1d872e67630--感谢这边文章的作者,我从里面得到了启发


http://hi.baidu.com/justtmiss/item/f3f6d50ce395f1d872e67630



    NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d", [indexPath section], [indexPath row]];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:

                             CellIdentifier];

    if (cell == nil) {  

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault

                                       reuseIdentifier: CellIdentifier] autorelease];

    }


这是我程序里面的正确代码,由于目前项目紧张。我打算过一段时间在好好描述一下问题和。


    
[3] 关于手逛数值的一些想法
    来源: 互联网  发布时间: 2014-02-18
关于手游数值的一些想法
1、先难后易、玩家会接受 如果先易后难 玩家很难接受
2、数值在运营之前一定要设计好 坚决不能改 玩家玩着玩着就习惯了、要不然重要数值改来改去 玩家很容易流失
3、数值要做精细 不能做那种让人爽的数值

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
编程技术其它 iis7站长之家
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3