????? 為了能在攝像頭預覽的時候,背景有個矩形框、或一些坐標、橫線來標示關鍵位置,真讓雜家費勁心思了。苦苦研究了兩天,毫無進展。baidu了若干資料,大都是提出這個問題,但怎么解決的沒有說,都不了了之。后來轉而google,又研究了兩天,終于完美解決啦!
1,網上介紹的攝像頭預覽,一般是用一個surfaceview,為了能讓其正常預覽視頻,設置屬性??????
mySurfaceView.setZOrderOnTop(true);????????
mySurfaceHolder = mySurfaceView.getHolder();
mySurfaceHolder.setFormat(PixelFormat.TRANSPARENT)
我先前也是在這種思路下,看能否加畫個矩形框。這篇[http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html](http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html)文章提到一種方法,是用一個surfaceview,然后自己定義一個繼承View的畫矩形框的類DrawCaptureRect,經我實踐,發現還是不中。用這種思路,在攝像頭未預覽的時候可以看到紅色矩形框,但一點擊預覽,矩形框就被覆蓋了。
2,還有一種思路是,在預覽surfaceview的callback里面,取到canvas畫布,然后畫。這種思路也行不通,程序直接掛掉!
3,后來我想到了framelayout,用幀布局,融合第一種方法的思路,結果還是未能解決預覽的時候,視頻遮擋矩形框的問題。
4,還有人提出,給surfaceview或其所在的布局文件里加一個帶矩形框的圖片的方法,更是行不通!說這話的人真是站著不腰疼,別說背景設成帶圖片的矩形框,就是背景設成有顏色的,預覽的surfaceview就不顯示了,被遮擋了。
????????? **原來,當SurfaceHolder對象的類型設置為SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS時就只能拍照不能繪制了**,這就是為什么第二種思路程序會直接掛掉的原因。為了能夠預覽視頻的同時繪制矩形框等信息,需要用兩個同樣大小的SurfaceView放在一個FrameLayout里,頂層的SurfaceView設成setZOrderOnTop(true);???setFormat(PixelFormat.TRANSPARENT)?;預覽的Surfaceview這兩個屬性就不用設置了。
???首先在包yan.guoqi.testphoto下新建一個類SVDraw,如圖:

源碼如下:
~~~
package yan.guoqi.testphoto;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
/*定義一個畫矩形框的類*/
public class SVDraw extends SurfaceView implements SurfaceHolder.Callback{
protected SurfaceHolder sh;
private int mWidth;
private int mHeight;
public SVDraw(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
sh = getHolder();
sh.addCallback(this);
sh.setFormat(PixelFormat.TRANSPARENT);
setZOrderOnTop(true);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int w, int h) {
// TODO Auto-generated method stub
mWidth = w;
mHeight = h;
}
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
void clearDraw()
{
Canvas canvas = sh.lockCanvas();
canvas.drawColor(Color.BLUE);
sh.unlockCanvasAndPost(canvas);
}
public void drawLine()
{
Canvas canvas = sh.lockCanvas();
canvas.drawColor(Color.TRANSPARENT);
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(Color.RED);
p.setStyle(Style.STROKE);
//canvas.drawPoint(100.0f, 100.0f, p);
canvas.drawLine(0,110, 500, 110, p);
canvas.drawCircle(110, 110, 10.0f, p);
sh.unlockCanvasAndPost(canvas);
}
}
~~~
類里面的方法drawLine()就是畫預覽視頻時背景矩形的,由于我需畫一條線,上面程序就是畫一條線和一個圓的。需要畫什么圖形,就在這里改!
注意在建這個類時構造函數里一定要有
1. ????public?SVDraw(Context?context,?AttributeSet?attrs)?{??
1. ????????super(context,?attrs);??
AttributeSet?attrs這個參數,否則是不能在xml文件里正常解析的。先前提到的[http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html](http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html)這位就沒有引用這個參數,所以后來用了
addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT))? 將這個對象加到布局中去!
**上面的類建好之后,在布局文件里引用他,如下:**
~~~
<?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" >
<FrameLayout
android:id="@+id/myFramelayout"
android:layout_width="fill_parent"
android:layout_height="800px"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/mySurfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:visibility="visible" />
<yan.guoqi.testphoto.SVDraw
android:id="@+id/mDraw"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
<LinearLayout
android:id="@+id/LinearLayout01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
android:paddingTop="10dip" >
<Button
android:id="@+id/btnPreview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="預覽"
android:textSize="28sp" />
<Button
android:id="@+id/btnPhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拍照"
android:textSize="28sp" />
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:textSize="28sp" />
</LinearLayout>
</LinearLayout>
~~~
注意上面兩個surfaceview是同樣大小的,mySurfaceView是預覽視頻的,mDraw是用來畫矩形的。
接下來就是在主Activity里引用這個mDraw。首先定義變量private SVDraw? mSVDraw = null;? 然后mSVDraw = (yan.guoqi.testphoto.SVDraw)findViewByIf(R.id.mDraw)。之后mSVDraw就可以用了,至于什么時候來畫這個矩形,有人是在按下拍照按鈕后,我選擇的是在按下預覽按鈕后,
~~~
case R.id.btnPreview:
Toast.makeText(TestPhotoActivity.this,
"您按了預覽按鈕",
Toast.LENGTH_SHORT).show();
initCamera();
mDraw.setVisibility(View.VISIBLE);
mDraw.drawLine();
break;
~~~
讓其可見,然后調用drawLine()方法就可以了!你可以隨時控制讓其可見或者隱藏!
將上面這些代碼融合我[http://blog.csdn.net/yanzi1225627/article/details/7926994](http://blog.csdn.net/yanzi1225627/article/details/7926994)文章里[http://download.csdn.net/detail/yanzi1225627/4538626](http://download.csdn.net/detail/yanzi1225627/4538626)這里的源碼就可以了!即可以預覽,自動聚焦,縮放標準大小,背景有矩形框!
來張圖,有圖有真相

反思:其實用第一種[http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html](http://blog.sina.com.cn/s/blog_4e6922ab01010gfz.html)這里的思路和本篇的思路合并起來,應該也是可行的,只不過一個是繼承的view一個是surfaceview,將AttributeSet?attrs加上。只要處理好誰是頂層的view誰設成透明,預覽視頻的surfaceview設成底層,在且要在xml屬性文件里設成visible就可以了。有興趣的自己試驗吧。感謝大牛[http://blog.csdn.net/xinzheng_wang/article/details/7712285](http://blog.csdn.net/xinzheng_wang/article/details/7712285)對后生的指點!
???????????????????????????????????????????????????????????????????????????????????????????????????????? -------------------作者yanzi1225627,轉載請注明
- 前言
- Linux下使用QT調用opencv讀取攝像頭視頻 調試心得
- Android開發 攝像頭SurfaceView預覽 背景帶矩形框 實現(原理:雙surfaceview,頂層畫矩形框,底層預覽視頻)
- Android開發:安裝NDK,移植OpenCV2.3.1,JNI調用OpenCV全過程
- 2013新春奉送:Android攝像頭開發完美demo---(循環聚焦,縮放大小,旋轉picture,查詢支持的picturesize, ImageButton按鍵效果)
- 如何設置ImageButton按鍵按下去后的 特效----(如類似風車旋轉的動畫特效)
- Android攝像頭:只拍攝SurfaceView預覽界面特定區域內容(矩形框)---完整實現(原理:底層SurfaceView+上層繪制ImageView)
- Android開發:SurfaceView上新建線程繪制旋轉圖片 及 刷新特定區域(臟矩形)
- Android開發:ImageView上繪制旋轉圓環(透明度不同的旋轉圓環,利用canvas.drawArc實現)
- Android上掌紋識別第一步:基于OpenCV的6種膚色分割 源碼和效果圖
- Android開發:實時處理攝像頭預覽幀視頻------淺析PreviewCallback,onPreviewFrame,AsyncTask的綜合應用
- Android攝像頭開發:拍照后添加相框,融合相框和圖片為一副 圖片
- Android(OpenCV) NDK開發: 0xdeadbaad(code=1)錯誤 及 關閉armeabi和libnative_camera_r2.2.2.so的生成
- Android攝像頭開發:實時攝像頭視頻預覽幀的編碼問題(二)
- setContentView切換頁面(無需每次都findViewById)-----二
- Android開發:setContentView切換界面,自定義帶CheckBox的ListView顯示SQlite條目-----實現