- 浏览: 485511 次
文章分类
最新评论
Android Camera开发:给摄像头预览界面加个ZoomBar(附完整代码下载)
废话不说了,就是加个seekbar,拖动的话能够调节焦距,让画面变大或缩小。下面是核心程序:
一,camera的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/BestWish" tools:context=".StandardCamera" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <SurfaceView android:id="@+id/previewSV" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </FrameLayout> <LinearLayout android:id="@+id/zoomLayout" android:layout_width="wrap_content" android:layout_height="40dp" android:layout_centerInParent="true" android:layout_centerHorizontal="true" android:orientation="horizontal" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="-" android:textColor="#ffffff" android:textSize="30dip"/> <SeekBar android:id="@+id/seekbar_zoom" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:progressDrawable="@drawable/seekbar_style" android:thumb="@drawable/ic_launcher" android:thumbOffset="0dp" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+" android:textColor="#ffffff" android:textSize="30dip" /> </LinearLayout> </RelativeLayout> <ImageButton android:id="@+id/photoImgBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/photo_img_btn" /> </LinearLayout>
其中里面嵌套的LinearLayout就是那个ZoomBar,最外面我用了相对布局,发现相对布局用起来还是很好用的。为了方便以后扩展,Camera的SurfaceView用的帧布局。注意SeekBar的几个参数,其中的progressDrawable是指那个横条的形状,可以直接用个图片,也可以写个xml文件。这里用的是xml,当然用图片很简单。seekbar_style.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <corners android:radius="5dip" /> <gradient android:startColor="#ff9d9e9d" android:centerColor="#ff5a5d5a" android:centerY="0.75" android:endColor="#ff747674" android:angle="270" /> </shape> </item> </layer-list>
下面的android:thumb是滑动的那个手柄,本来我是写了一个xml文件,名字为thumb.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 按下状态 --> <item android:state_focused="true" android:state_pressed="true"><shape android:shape="oval"> <gradient android:angle="0" android:centerColor="#FF00FF00" android:endColor="#000000" android:gradientRadius="8" android:startColor="#FFFF0000" android:type="radial" /> <size android:height="20dip" android:width="20dip"></size> </shape></item> </selector>
无奈啥也显示不出来,索性直接找了个粗糙的图片,见谅哈!
二,整个程序的主代码:
package yan.guoqi.camera; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import yan.guoqi.rectphoto.R; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ColorMatrixColorFilter; import android.graphics.Matrix; 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.PreviewCallback; import android.hardware.Camera.ShutterCallback; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.view.WindowManager; import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; public class StandardCamera extends Activity implements SurfaceHolder.Callback, PreviewCallback{ private static final String tag="StandardCamera"; private boolean isPreview = false; private SurfaceView mPreviewSV = null; //棰勮SurfaceView private SurfaceHolder mySurfaceHolder = null; private ImageButton mPhotoImgBtn = null; private Camera myCamera = null; private Bitmap mBitmap = null; private AutoFocusCallback myAutoFocusCallback = null; boolean flag = true; private SeekBar mZoomBar = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN; Window myWindow = this.getWindow(); myWindow.setFlags(flag, flag); setContentView(R.layout.activity_rect_photo); initView(); mySurfaceHolder = mPreviewSV.getHolder(); mySurfaceHolder.setFormat(PixelFormat.TRANSLUCENT); mySurfaceHolder.addCallback(this); mySurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); myAutoFocusCallback = new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { // TODO Auto-generated method stub if(success) { Log.i(tag, "myAutoFocusCallback: success..."); } else { Log.i(tag, "myAutoFocusCallback: 澶辫触浜�?."); } } }; //添加ZoomBar mZoomBar = (SeekBar)findViewById(R.id.seekbar_zoom); mZoomBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // TODO Auto-generated method stub Parameters p = myCamera.getParameters(); p.setZoom(progress); myCamera.setParameters(p); } }); } public void initView(){ mPreviewSV = (SurfaceView)findViewById(R.id.previewSV); WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); LayoutParams lpSV = mPreviewSV.getLayoutParams(); lpSV.width = display.getWidth(); lpSV.height = (int) ((float)display.getHeight()*0.75); mPreviewSV.setLayoutParams(lpSV); mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn); LayoutParams lp = mPhotoImgBtn.getLayoutParams(); lp.width = 240; lp.height = 240; mPhotoImgBtn.setLayoutParams(lp); mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener()); mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener()); } public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { // TODO Auto-generated method stub Log.i(tag, "SurfaceHolder.Callback:surfaceChanged!"); initCamera(); } public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub myCamera = Camera.open(); try { myCamera.setPreviewDisplay(mySurfaceHolder); Log.i(tag, "SurfaceHolder.Callback: surfaceCreated!"); } catch (IOException e) { // TODO Auto-generated catch block if(null != myCamera){ myCamera.release(); myCamera = null; } e.printStackTrace(); } } public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub Log.i(tag, "SurfaceHolder.Callback锛歋urface Destroyed"); if(null != myCamera) { myCamera.setPreviewCallback(null); myCamera.stopPreview(); isPreview = false; myCamera.release(); myCamera = null; } } public void initCamera(){ if(isPreview){ myCamera.stopPreview(); } if(null != myCamera){ Camera.Parameters myParam = myCamera.getParameters(); myParam.setPictureFormat(PixelFormat.JPEG);//璁剧疆鎷嶇収鍚庡瓨鍌ㄧ殑鍥剧墖鏍煎紡 //List<Size> pictureSizes = myParam.getSupportedPictureSizes(); //List<Size> previewSizes = myParam.getSupportedPreviewSizes(); // for(int i=0; i<pictureSizes.size(); i++){ // Size size = pictureSizes.get(i); // Log.i(tag, "initCamera:pictureSizes: width = "+size.width+"height = "+size.height); // } // for(int i=0; i<previewSizes.size(); i++){ // Size size = previewSizes.get(i); // Log.i(tag, "initCamera:鎽勫儚澶存敮鎸佺殑previewSizes: width = "+size.width+"height = "+size.height); // // } myParam.setPictureSize(1280, 960); // myParam.setPreviewSize(960, 720); // //myParam.set("rotation", 90); myCamera.setDisplayOrientation(90); List<String> focuseMode = (myParam.getSupportedFocusModes()); for(int i=0; i<focuseMode.size(); i++){ Log.i(tag, focuseMode.get(i)); if(focuseMode.get(i).contains("continuous")){ myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); } else{ myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); } } //设置mZoomBar的最大值 mZoomBar.setMax(myParam.getMaxZoom()); myCamera.setParameters(myParam); myCamera.startPreview(); myCamera.autoFocus(myAutoFocusCallback); isPreview = true; } } ShutterCallback myShutterCallback = new ShutterCallback() { public void onShutter() { // TODO Auto-generated method stub Log.i(tag, "myShutterCallback:onShutter..."); } }; PictureCallback myRawCallback = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub Log.i(tag, "myRawCallback:onPictureTaken..."); } }; PictureCallback myJpegCallback = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub Log.i(tag, "myJpegCallback:onPictureTaken..."); if(null != data){ mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);//data鏄瓧鑺傛暟鎹紝灏嗗叾瑙f瀽鎴愪綅鍥� myCamera.stopPreview(); isPreview = false; } Matrix matrix = new Matrix(); matrix.postRotate((float)90.0); Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, false); if(null != rotaBitmap) { saveJpeg(rotaBitmap); } myCamera.startPreview(); isPreview = true; } }; public class PhotoOnClickListener implements OnClickListener{ public void onClick(View v) { // TODO Auto-generated method stub if(isPreview && myCamera!=null){ myCamera.takePicture(myShutterCallback, null, myJpegCallback); } } } public void saveJpeg(Bitmap bm){ String savePath = "/mnt/sdcard/rectPhoto/"; File folder = new File(savePath); if(!folder.exists()) { folder.mkdir(); } long dataTake = System.currentTimeMillis(); String jpegName = savePath + dataTake +".jpg"; Log.i(tag, "saveJpeg:jpegName--" + jpegName); //File jpegFile = new File(jpegName); try { FileOutputStream fout = new FileOutputStream(jpegName); BufferedOutputStream bos = new BufferedOutputStream(fout); // Bitmap newBM = bm.createScaledBitmap(bm, 600, 800, false); bm.compress(Bitmap.CompressFormat.JPEG, 100, bos); bos.flush(); bos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public class MyOnTouchListener implements OnTouchListener{ public final float[] BT_SELECTED=new float[] { 2, 0, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0, 2, 0, 2, 0, 0, 0, 1, 0 }; public final float[] BT_NOT_SELECTED=new float[] { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 }; public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(event.getAction() == MotionEvent.ACTION_DOWN){ v.getBackground().setColorFilter(new ColorMatrixColorFilter(BT_SELECTED)); v.setBackgroundDrawable(v.getBackground()); } else if(event.getAction() == MotionEvent.ACTION_UP){ v.getBackground().setColorFilter(new ColorMatrixColorFilter(BT_NOT_SELECTED)); v.setBackgroundDrawable(v.getBackground()); } return false; } } @Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed(); StandardCamera.this.finish(); } class UpdateThread implements Runnable{ public void run() { // TODO Auto-generated method stub while(flag){ if(myCamera!=null && isPreview) myCamera.autoFocus(myAutoFocusCallback); //鑷姩鑱氱劍 myCamera.setOneShotPreviewCallback(StandardCamera.this); //onPreviewFrame閲屼細鎺ュ彈鍒版暟鎹�? myCamera.stopPreview(); //鍋滄棰勮 flag = false; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public void onPreviewFrame(byte[] data, Camera camera) { // TODO Auto-generated method stub } }
需要注意的有以下几点:
1,为了让程序适用不同的手机,onCreate函数里用如下代码初始化SurfaceView的大小,避免以前写死的方法:
public void initView(){
mPreviewSV = (SurfaceView)findViewById(R.id.previewSV);
WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
LayoutParams lpSV = mPreviewSV.getLayoutParams();
lpSV.width = display.getWidth();
lpSV.height = (int) ((float)display.getHeight()*0.75);
mPreviewSV.setLayoutParams(lpSV);
mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn);
LayoutParams lp = mPhotoImgBtn.getLayoutParams();
lp.width = 240;
lp.height = 240;
mPhotoImgBtn.setLayoutParams(lp);
mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener());
mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener());
}
2,关于ZoomBar的代码片段很简短,如下:
mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn);
LayoutParams lp = mPhotoImgBtn.getLayoutParams();
lp.width = 240;
lp.height = 240;
mPhotoImgBtn.setLayoutParams(lp);
mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener());
mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener());
}
//添加ZoomBar
mZoomBar = (SeekBar)findViewById(R.id.seekbar_zoom);
mZoomBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
Parameters p = myCamera.getParameters();
p.setZoom(progress);
myCamera.setParameters(p);
}
});
3,在initCamera函数里,查询camera支持的聚焦模式,如果带连续视频聚焦则使用连续视频聚焦,否则使用自动聚焦:
mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn);
LayoutParams lp = mPhotoImgBtn.getLayoutParams();
lp.width = 240;
lp.height = 240;
mPhotoImgBtn.setLayoutParams(lp);
mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener());
mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener());
}
List<String> focuseMode = (myParam.getSupportedFocusModes());
for(int i=0; i<focuseMode.size(); i++){
Log.i(tag, focuseMode.get(i));
if(focuseMode.get(i).contains("continuous")){
myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
else{
myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
}
4,同样在initCamera函数里,设置ZoomBar的最大值:
//设置mZoomBar的最大值
mZoomBar.setMax(myParam.getMaxZoom());
后续将写专文分析Camera4.0的源码,并且模仿到自己的代码中!
源码下载链接:http://download.csdn.net/detail/yanzi1225627/6421779
相关推荐
带zoombar的camera,参见http://blog.csdn.net/yanzi1225627/article/details/12860127
leaflet-control-boxzoom.css
基于matlab实现的相移光纤光栅(FBG.rar
配套设备仪器用
数据来源:中国电力统计NJ-2021版
基于matlab实现烟花寻优算法,自己编的.rar
数据来源:中国电力统计NJ-2021版
俄罗斯方块游戏最初是由俄罗斯人阿列克谢·帕基特诺夫在1984年开发的休闲小游戏,曾几何时它创造了无可匹敌的商业价值,影响了一代休闲小游戏的开发与产业链。随着信息时代科技时代的不断发展和变化,计算机已经普及到每一个人的生活中,在繁忙的工作生活中,这一类休闲小游戏给人们带来了些许的放松。 这篇论文详细的描述分析了经典传统的俄罗斯方块实现的基本思路和一些基本游戏规则,在此基础之上,更进一步地开发出俄罗斯方块的创新创意模式,在经典游戏基础上开发出随着分数增高而等级增高难度加大的模式,并且创意性的开发出可操控方块颜色变换的模块,并且增添了游戏声音和音乐模块。本论文对上述功能给出了具体实现流程、详细描述、和一些源代码。 本论文阐述了俄罗斯方块游戏的开发和发展历史、开发此游戏的意义以及开发环境并根据软件工程开发软件和java编写程序的相关知识,对程序的需求分析、概要设计、详细设计与实现、调试运行进行了一系列描述。 此次程序设计是在Microsoft Windows 7系统下,以Java为开发语言,在Eclipse开发平台上进行游戏的设计与实现。
一个基于ArkTS开源的鸿蒙next版的物流APP源代码
数据来源:中国人口与就业统计NJ-2023版
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
limbox86pcemulator_241983-3.apk
数据来源:中国劳动统计NJ-2023版
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
数据来源:中国人口与就业统计NJ-2023版
2023年华数杯全国大学生数学建模大赛的大数据B题论文全文,文中框架完整,内容较为详细,此论文获得华数杯三等奖,为了避免二次外传,本文设置了水印,请各位注意文章隐私,同时由于限制,在此并未上传相关代码,若需要代码或答疑等服务,请私聊作者。 日常生活中五彩;缤纷的不透明有色制品是由着色剂染色而成。因此,不透明制品的配色对其外观美观度和市场竞争力起着重要作用。然而,传统的人工配色存在一定的局限性,如主观性强、效率低下等。因此,研究如何通过计算机方法来实现不透明制品的配色具有重要意义。 以下是部分题目 光通过物体传播有吸收、反射和透射三种方式。对于不透明制品来说,大部分光线会被其表面吸收或反射。吸收和反射的光线在经过透明度等校正后按波长分解成不同的颜色成分,形成光谱图。该光谱图通常由 400--700nm 波段的各色光组成。为简化计算,最终配色后的颜色的反射率以 20nm 为间隔的光谱数据来表示。对于不透明材料而言,吸收系数 K/散射系数 S 的比值与反射率 R 之间存在一定关系,具体请参考文献【1】《计算机配色理论及算法的研究》中的 K-M光学模型。基于光学模型得到的颜色参数,可应用于色
附件是 华为 OD 机考攻略_加强版,文件绿色安全,请大家放心下载,仅供交流学习使用,无任何商业目的!
数据来源:中国劳动统计NJ-2023版
数据来源:中国电力统计NJ-2021版
Qt实现停车场管理软件 入库、出库、导航 Qt mysql操作 Qt 解析tiled生成的xml文件,并绘制图片 Qt 绘图 Qsql, QSqlDatabase, QtXml, QVector ,QImage, QPrinter .... 环境 ubuntu + mysql Todo install qt 5.3 install mysql 5 import sql file run