- 浏览: 677173 次
- 性别:
- 来自: 安徽
文章分类
- 全部博客 (252)
- Html/Div+CSS (12)
- Js/Jquery (34)
- Flex (2)
- Ajax (3)
- Java (35)
- C# (15)
- Spring (16)
- Hibernate (13)
- Struts2 (12)
- Struts1 (7)
- DWR (1)
- iBatis/myBatis (9)
- Tag(JSTL、EL) (1)
- Android (44)
- SQL (7)
- SEO (7)
- Exception (3)
- Tool (10)
- Other (3)
- WebService (9)
- Apache (7)
- Ext (0)
- Utils (12)
- thinking in programme (2)
- Hadoop (0)
- ActiveMQ (0)
- HTML5/CSS3 (0)
- WPF (1)
- NodeJs (1)
- 设计模式 (0)
- 程序人生 (1)
- 随笔 (1)
- Linux (1)
- Load Balance (0)
最新评论
-
drinkjava2:
太复杂了而且不通用,利用ThreadLocal可完美解决这一问 ...
JDBC的多条件动态查询 -
u013107014:
multipartRequest.getFiles(" ...
多文件上传 by MultipartFile and Multiple -
liyys:
可惜没讲你mysql数据库的表的设计
iBatis入门 -
Mapple_leave:
效果还是挺不错的,谢谢了。
中文简体与繁体的转换 -
arcpad:
JS禁用浏览器退格键
一、摄像头拍照
前面说媒体播放 时了解了 SurfaceView 最大的特点就是提供了一个高速的更新空间,那么如果说现在要进行图像的捕获,那么肯定要跟随摄像头一起变化,那么这块空间很明显必须使用高速的刷新频率。
使用 SurfaceView 组件可以进行视频文件的播放,而同样可以继续利用 SurfaceView 实现拍照的浏览功能,在支持拍照的手机上,都会为用户提供一个预览的屏幕显示当前摄像头所采集到的图片,而这种功能可以利用 SurfaceView 实现, SurfaceView 之中的操作核心就是在于 android.view. SurfaceHolder 对象的操作,前面说了可以通过 SurfaceView 取得一个 SurfaceHolder 对象,可是如果要想实现拍照的功能,首先用户必须手动实现 android.view. SurfaceHolder.Callback 这个操作接口,在此接口中定义了高速图像浏览时的各个操作。
No. |
方法 |
描述 |
1 |
Public abstract void surfaceChanged(SurfaceHolder holder,int format,int width,int height) |
当预览界面的格式和大小发生改变时会触发此操作 |
2 |
Public abstract void surfaceCreated(SurfaceHolder holder) |
当预览界面被创建时会触发此操作 |
3 |
Public abstract void surfaceDestroyed(SurfaceHolder holder) |
当预览界面关闭时会触发此操作 |
Android.hardware.Camera 进行调用摄像头的操作类,此类主要负责完成拍照图片的参数设置及保存,需要注意的是摄像头只能被一个设备所支持。
Camera 类中定义的内部接口:
No. |
接口名称 |
描述 |
1 |
Android.hardware.Camera.AutoFocusCallback |
自动对焦的回调操作 |
2 |
Android.hardware.Camera.ErrorCallback |
错误出现时的回调操作 |
3 |
Android.hardware.Camera.OnZoomChangedListener |
显示区域改变时的回调操作 |
4 |
Android.hardware.Camera.PictureCallback |
图片生成时的回调操作 |
5 |
Android.hardware.Camera.PreviewCallback |
预览时的回调操作 |
6 |
Android.hardware.Camera.ShutterCallback |
按下快门后的回调操作 |
范例:预览,拍照
因为需要将照片保存在 sdcard 下,所以需要配置一些权限,同时将屏幕的方向设置为横屏
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.iflytek.demo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".CameraActivity" android:screenOrientation="landscape" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 摄像头 --> <uses-permission android:name="android.permission.CAMERA" /> <!-- SDCard权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 写入扩展设备 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> </manifest>
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/but" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="照相" /> <SurfaceView android:id="@+id/surface" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
下面我们通过 SurfaceView 捕获图像,而后使用按钮进行图像的拍照。
现在必须将摄像头捕获到的内容设置到 SurfaceView 之中。
如果要想实现拍照的功能,那么前提一定是已经对焦成功。
CameraActivity.java
package com.iflytek.demo; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.MessageFormat; import java.util.List; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.ShutterCallback; import android.os.Bundle; import android.os.Environment; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class CameraActivity extends Activity { private SurfaceView surfaceView = null; private Button btn = null; private SurfaceHolder surfaceHolder = null; private Camera camera = null; private boolean previewRunning = true; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.btn = (Button) super.findViewById(R.id.but); this.surfaceView = (SurfaceView) super.findViewById(R.id.surface); this.surfaceHolder = this.surfaceView.getHolder(); this.surfaceHolder.addCallback(new MySurfaceViewCallback()); this.surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); this.surfaceHolder.setFixedSize(960, 640); this.btn.setOnClickListener(new OnClickListenerImpl()); } private class OnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { if (CameraActivity.this.camera != null) { // 实现自动对焦功能,这里最好不要写自动对焦的,否则可能会对焦不成功 // CameraActivity.this.camera // .autoFocus(new AutoFocusCallbackImpl()); CameraActivity.this.camera.takePicture(shutterCallback, pictureCallback, jpgCallback); } } } /** * * @author xdwang * * @create 2012-11-13 下午10:24:18 * * @email:xdwangiflytek@gmail.com * * @description 捕获屏幕 * */ private class MySurfaceViewCallback implements SurfaceHolder.Callback { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { CameraActivity.this.camera = Camera.open(0); // 取得第一个摄像头,可能存在多个,0表示后面的,1表示前置摄像头 Parameters parameters = CameraActivity.this.camera.getParameters(); List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); Camera.Size pictureSize = previewSizes.get(0); parameters.setPreviewSize(pictureSize.width, pictureSize.height); //用以下方式会报:java.lang.RuntimeException: setParameters failed,因为不同手机的分辨率是不一样的 //WindowManager manager = (WindowManager) CameraActivity.this.getSystemService(Context.WINDOW_SERVICE); //Display display = manager.getDefaultDisplay(); //parameters.setPreviewSize(display.getWidth(), display.getHeight());// 设置预览大小,即手机屏幕大小 parameters.setPreviewFrameRate(5); // 每秒5帧 parameters.setPictureFormat(PixelFormat.JPEG); // 图片形式 parameters.set("jpen-quality", 80);// 设置图片质量,最高100 CameraActivity.this.camera.setParameters(parameters); try { CameraActivity.this.camera .setPreviewDisplay(CameraActivity.this.surfaceHolder); } catch (IOException e) { } CameraActivity.this.camera.startPreview(); // 进行预览 CameraActivity.this.previewRunning = true; // 已经开始预览 } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (CameraActivity.this.camera != null) { if (CameraActivity.this.previewRunning) { CameraActivity.this.camera.stopPreview(); // 停止预览 CameraActivity.this.previewRunning = false; } CameraActivity.this.camera.release(); } } } /** * * @author xdwang * * @create 2012-11-13 下午10:46:57 * * @email:xdwangiflytek@gmail.com * * @description 自动对焦 * */ private class AutoFocusCallbackImpl implements AutoFocusCallback { @Override public void onAutoFocus(boolean success, Camera camera) { if (success) { // 对焦成功 CameraActivity.this.camera.takePicture(shutterCallback, pictureCallback, jpgCallback); } } } /** * 生成新的图片 */ private PictureCallback jpgCallback = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // 保存图片的操作 // 所有的数据保存在byte数组中,将byte数组转换为Bitmap Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); String fullFileName = MessageFormat.format( "{0}{1}xdwang{1}xdwang_{2}.jpg", Environment .getExternalStorageDirectory().toString(), File.separator, System.currentTimeMillis()); File file = new File(fullFileName); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); // 创建文件夹 } try { BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos); // 向缓冲区之中压缩图片 bos.flush(); bos.close(); Toast.makeText(CameraActivity.this, "拍照成功,照片已保存在" + fullFileName + "文件之中!", Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(CameraActivity.this, "拍照失败!", Toast.LENGTH_SHORT) .show(); } //为下一次拍照做准备 CameraActivity.this.camera.stopPreview(); CameraActivity.this.camera.startPreview(); } }; /** * 按下快门后的操作 */ private ShutterCallback shutterCallback = new ShutterCallback() { @Override public void onShutter() { // 按下快门之后进行的操作 } }; /** * 原始图像 */ private PictureCallback pictureCallback = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { } }; }
二、多点触控
多点触控指可以同事对用户的多个屏幕触摸点进行监听,并进行相应处理的一种操作,在 Activity 类中,使用 onTouchEvent() 方法完成多点触控,此方法定义如下:
Public Boolean onTouchEvent(MotionEvent event){}
可以发现,在此方法中有一个 android.view.MotionEvent 类的时间对象,实际上用户可以通过该事件对象完成对多个触摸点的操作监听,而 MotionEvent 类的常用方法如下:
No. |
方法 |
描述 |
1 |
Public final int getAction() |
返回操作的 Action 类型,如按下 or 松开 |
2 |
Public final long getDownTimea() |
返回按下的时间 |
3 |
Public final long getEventTime() |
事件操作的结束时间 |
4 |
Public final int getPointerCount() |
返回同时触摸点的个数 |
5 |
Public final float getX(int pointerIndex) |
取得指定触摸点的 X 坐标 |
6 |
Public final float getY(intpointerIndex) |
取得指定触摸点的 Y 坐标 |
比如完成图片的缩放操作:
package com.iflytek.demo; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.os.Bundle; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MultitouchActivity extends Activity { private static final int SCALEBASIC = 3;// 调整的比率 private int imageX = 0; // 计算图片的X轴 private int imageY = 0; // 计算图片的Y轴 private SurfaceHolder surfaceHolder = null; private int screenWidth = 0; private int screenHeight = 0; private int imageWidth = 0; private int imageHeight = 0; private Bitmap bitmap = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.screenWidth = super.getWindowManager().getDefaultDisplay() .getWidth();// 取得屏幕的宽度 this.screenHeight = super.getWindowManager().getDefaultDisplay() .getHeight(); this.bitmap = BitmapFactory.decodeResource(super.getResources(), R.drawable.abc); this.imageWidth = this.bitmap.getWidth(); this.imageHeight = this.bitmap.getHeight(); this.imageX = (this.screenWidth - this.imageWidth) / 2; this.imageY = (this.screenHeight - this.imageHeight) / 2; super.setContentView(new MySurfaceView(this));// 使用SurfaceView封装 } private class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { public MySurfaceView(Context context) { super(context); MultitouchActivity.this.surfaceHolder = super.getHolder(); MultitouchActivity.this.surfaceHolder.addCallback(this);// 添加Callback操作 super.setFocusable(true); // 获得焦点,进行触摸事件 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {// SurfaceView改变 } @Override public void surfaceCreated(SurfaceHolder holder) {// SurfaceView创建 MultitouchActivity.this.setImage(1.0f, 350, 500);// 设置默认显示图片 } @Override public void surfaceDestroyed(SurfaceHolder holder) {// 销毁 } } /** * @descrption 设置图片 * @author xdwang * @create 2012-11-14下午8:08:41 * @param scale * @param width * @param height */ private void setImage(float scale, int width, int height) { // 改变之后修改图片 Canvas canvas = MultitouchActivity.this.surfaceHolder.lockCanvas(); // 获取画布 Paint paint = new Paint();// 填充底色 canvas.drawRect(0, 0, MultitouchActivity.this.screenWidth, MultitouchActivity.this.screenHeight, paint);// 绘制矩形 Matrix matrix = new Matrix();// 控制图像 matrix.postScale(scale, scale); // 缩放设置,等量缩放 Bitmap target = Bitmap.createBitmap(MultitouchActivity.this.bitmap, 0, 0, width, height, matrix, true);// 创建新图片 this.imageWidth = target.getWidth(); // 取得新图片宽度 this.imageHeight = target.getHeight(); this.imageX = (this.screenWidth - this.imageWidth) / 2;// 重新计算X坐标 this.imageY = (this.screenHeight - this.imageHeight) / 2; canvas.translate(this.imageX, this.imageY); // 图像平移,平移到指定的位置 canvas.drawBitmap(this.bitmap, matrix, paint);// 重新绘图 MultitouchActivity.this.surfaceHolder.unlockCanvasAndPost(canvas);// 解锁画布,并提交图象 } /** * 触摸事件 */ @Override public boolean onTouchEvent(MotionEvent event) { int pointCount = event.getPointerCount();// 取得触控点数量 if (pointCount == 2) { float pointA = event.getY(0);// 取得第一个触摸点的Y坐标 float pointB = event.getY(1);// 取得第2个触摸点的Y坐标 if (pointA < pointB) {// 让pointA保存最大点 float temp = pointA; pointA = pointB; pointB = temp; } if (!(event.getAction() == MotionEvent.ACTION_UP)) {// 用户按下 float scale = this.getScale(pointA, pointB) / SCALEBASIC;// 计算缩放量 MultitouchActivity.this.setImage(scale, 350, 500);// 重设图片 } } return super.onTouchEvent(event); } /** * @descrption 得到缩放比率 * @author xdwang * @create 2012-11-14下午8:15:25 * @param pointA * @param pointB * @return */ private float getScale(float pointA, float pointB) { float scale = pointA / pointB; return scale; } }
发表评论
-
This version of ADT requires android SDK
2013-07-25 16:45 1604Windows系统下用Eclipse开发工具开发An ... -
Android学习13-----网络通信(4) WebView组件
2012-11-27 09:18 2523WebView 是一个开发的浏览 ... -
Android学习13-----网络通信(3) 与Web Service进行通讯
2012-11-26 09:40 1901这里我们的WebService使用xFire开发。 ... -
Android学习13-----网络通信(2) 与Socket交换数据
2012-11-23 09:11 3313对于网络开发而言,最常用的交互模式:WebService、We ... -
Android学习13-----网络通信(1) 与WEB服务器交换数据
2012-11-22 09:11 2199与Web服务器交互: 如果手机要想与 web ... -
Android学习11-----多媒体技术(5) 媒体录制
2012-11-16 08:10 1899在Android中通过android.media ... -
Android学习11-----多媒体技术(3) 媒体播放
2012-11-14 08:25 1423在 Androi ... -
Android学习11-----多媒体技术(2) Animation
2012-11-13 08:47 2003一、渐变动画, Tweened Animation ... -
Android学习11-----多媒体技术(1) 绘制简单图形,Bitmap,Matrix
2012-11-12 08:48 1632一、绘制简单图 ... -
Android学习12-----手机服务(4) 传感器
2012-11-19 09:13 2026传感器一般用于游戏中,在 Android 系统中为 ... -
Android学习12-----手机服务(1) 取得电池电量和声音服务:AudioManager
2012-11-18 11:18 3517一、取得电池电量信息 ... -
Android学习10-----Android组件通信 (8) 桌面显示组件:AppWidget
2012-11-02 08:36 2044一、 AppWidget 在使用 Androi ... -
Android学习10-----Android组件通信 (7) 广播机制:Broadcast
2012-11-01 08:43 1523一、 广播: 广播也是一种信息的发送机制,在 ... -
Android学习10-----Android组件通信 (6) PendingIntent
2012-10-31 08:20 2276Intent 的主要功能是表示用 ... -
Android学习10-----Android组件通信 (5) Service
2012-10-30 08:25 1748Service 基本组成: ... -
Android学习10-----Android组件通信 (4) 消息机制
2012-10-29 08:22 1560在 Android 操作系统中存在着消息队列的操作 ... -
Android学习10-----Android组件通信 (3) ActivityGroup
2012-10-26 08:23 2341导航栏在 Android 中的应用是很常见的,前面 ... -
Android学习10-----Android组件通信 (2) Activity生命周期
2012-10-25 08:16 1293Activity 是整个 Android 平台的基 ... -
Android学习10-----Android组件通信 (1) Intent
2012-10-24 08:43 2029在一个项目之中,会由多个 Activity ... -
Android判断是否有网络连接
2013-04-25 16:34 1447Android中判断有时候因为功能的需求,需要判断是否有网络 ...
相关推荐
在Android平台上,手势识别与多点触控是移动应用开发中的关键组成部分,它们极大地提升了用户交互体验。Android系统提供了一套强大的API,使得开发者能够轻松地处理和解析用户的触摸事件,进而实现各种复杂的手势...
标题中的“行业分类-设备装置-多点触控的多媒体球幕演示仪及其多点触控方法”揭示了我们讨论的核心技术领域,即多点触控技术在多媒体球幕演示设备上的应用。这类设备通常用于展示高清晰度的影像、三维动画或科学模拟...
在本项目中,我们探索的是一个Android小程序,它是一个电子钢琴应用,支持多点触控功能,从而允许用户同时按下多个琴键,创造出更...希望这个项目能帮助你进一步了解Android编程以及多点触控技术在移动应用中的应用。
在Android开发中,实现多点触控控制字体大小是一项高级技术,这通常涉及到手势识别、事件处理以及UI动态更新等多个方面。本示例项目“Android高级应用源码-多点触控控制字体大小”提供了一个详细的参考实现,帮助...
在Android开发中,多点触控(Multi-Touch)技术是一项关键特性,它允许用户通过两个或更多手指来与屏幕交互,实现如缩放、旋转、拖动等操作。本项目"PhotoWallFallsDemo"就是一个典型的实例,演示了如何在Android...
在IT行业中,多点触控技术是用户界面交互的一个重要组成部分,尤其是在移动设备和触摸屏应用上。Flash AS3(ActionScript 3)是Adobe Flash Professional用于创建动态内容、交互式应用程序和游戏的主要编程语言。在...
在Android开发中,多点触控(Multi-Touch)是一项重要的功能,允许用户通过两个或更多的手指进行交互,如缩放、旋转等操作。本文将深入探讨如何在Android应用程序中实现图片的多点触控缩放功能。我们将讨论以下几个...
本实例源码是针对Android开发的多点触控功能的实现,通过分析和学习,开发者可以掌握如何在自己的应用程序中集成多点触控功能。 1. 多点触控基础 在Android中,多点触控主要通过`MotionEvent`类来实现。`...
AutoJs源码-教程_多点触控(6)。本资源购买前提醒:本源码都是实际autojs项目模板,安装好autojs直接运行即可打开。1、支持低版本autojs。2、资源仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您自己...
这个名为"Android 多点触控实例源码"的压缩包提供了实现这一功能的源代码,对于学习和理解Android多点触控编程具有极大的帮助。 1. **Android多点触控基础** - 触摸事件:Android系统通过`MotionEvent`类处理触摸...
在Android开发中,多点触控(Multitouch)是一项重要的功能,允许用户通过两个或更多的手指进行交互,如缩放、旋转、平移等操作。这个"android多点触控demo,两只手同时拖拽"是针对Android平台的一个示例项目,其...
AutoJs源码-教程_多点触控。本资源购买前提醒:本源码都是实际autojs项目模板,安装好autojs直接运行即可打开。1、支持低版本autojs。2、资源仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您自己承担!...
这个压缩包提供了五个不同的示例,旨在帮助开发者深入理解和实践Android中的多点触控和手势识别技术。 1. **多点触控(Multi-Touch)**: 多点触控允许用户通过同时触摸屏幕的多个点来与应用进行交互。在Android中...
在Android开发中,实现多点触控功能可以让用户更加自然地与应用进行交互,特别是对于图片查看、手势操作等场景非常实用。本教程将详细讲解如何实现一个最简单的Android多点触控图片放大功能,无需复杂的代码,主要...
总的来说,"BLE_HID_arduinoBLE多点触控"项目结合了物联网、嵌入式系统、无线通信和多点触控技术,提供了一种创新的交互方式,不仅适用于学习和探索,也对实际应用有着广阔的前景。通过不断的调试和完善,可以实现更...
在安卓(Android)平台上,开发多点触控功能是实现用户交互的重要部分,尤其是在创建复杂的触摸界面时。这个“安卓Android源码——多点触控实例源码.zip”压缩包包含了一个具体的多点触控应用的源代码,可以帮助...
Android开发实战经典_031008_多点触控视频教程.zip
这个"Android多点触控实例源码"提供了一个实用的学习资源,帮助开发者深入理解并实践Android中的多点触控技术。以下将详细介绍该源码中的关键知识点。 1. **MotionEvent**:在Android中,处理触摸事件的核心类是`...
"Android手势调节音量,亮度,进度"这个项目涵盖了Android开发中的多点触控手势识别、系统资源控制(音量、亮度)、UI组件(如SeekBar)的使用以及程序调试等多个知识点,为Android开发者提供了一个实用的学习案例。
多点触控技术是现代电子设备中不可或缺的一部分,尤其在智能手机、平板电脑和触摸屏显示器等领域广泛应用。这种技术允许用户通过同时使用一个或多个手指来与屏幕进行交互,提供了更为直观和自然的操作体验。本文将...