編輯:關於Android編程
就是仿照現在掃一掃的形式,周圍是半透明的遮擋,然後中間是全透明的,拍攝後只截取框內的內容
查了很多博客,實現起來真的太復雜了,本人比較怕麻煩所以在很多地方偷懶了
先上效果圖:
第一步:設置照相機預覽以及拍照
這是所有步驟的前提,沒有預覽,用戶怎麼知道自己拍的什麼呢。預覽用的是SurfaceView
這篇博文寫得已經十分詳細了,打開照相機,然後拍照,而且十分簡潔!不想別的博客一下就幾百行代碼不知所雲。這篇代碼可以復制下去當相機模版使用。
這裡遇到一個問題,就是預覽的效果是左轉90度的,拍出來也是左轉90度的,查了很多資料,大家統一的做法就是。在相機預覽那裡設置右旋90度,拍下的照片再右旋90度,具體的做法我會貼代碼
第二步:設置半透明邊框
很多博客的做法是繪圖呀什麼的,太過負責。
其實如果考慮簡單點的話,只要在surfaceView上面疊加一層圖片就好了,用Framelayout布局
就是背景半透明,中間扣掉
第三步:怎麼只拍攝框內的圖片
這個問題,很多博客都是長篇大論,什麼矩陣運算都用上了,雖然很強,但是不想看下去。
拍攝框內的圖片,就直接拍完整張照片之後,在照片裡面摳圖就好了啊。
Bitmap.createBitmap(bitmap,50,250,650,500);
自己算一下透明框大概在什麼位置,左上角的坐標是什麼,寬和高是什麼。用上述函數就可以在原照片摳圖了。
第四步:完善一點,加入點擊對焦
其實就是在點擊事件裡面調用對焦函數就行
總的代碼:
public class MainActivity extends AppCompatActivity { private SurfaceView surfaceview; private Camera camera; private Button take; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // 沒有標題 必須在設置布局之前找到調用 setContentView(R.layout.activity_main); /* getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, // 設置全屏顯示 WindowManager.LayoutParams.FLAG_FULLSCREEN); */ take = (Button)findViewById(R.id.take); surfaceview = (SurfaceView) findViewById(R.id.surfaceview); SurfaceHolder holder = surfaceview.getHolder(); holder.setFixedSize(176, 155);// 設置分辨率 holder.setKeepScreenOn(true); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // SurfaceView只有當activity顯示到了前台,該控件才會被創建 因此需要監聽surfaceview的創建 holder.addCallback(new MySurfaceCallback()); //拍照按鈕 take.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { takepicture(); } }); } //點擊事件 @Override public boolean onTouchEvent(MotionEvent event) { //對焦 camera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean b, Camera camera) { camera.cancelAutoFocus(); } }); return super.onTouchEvent(event); } /** * 監聽surfaceview的創建 * @author Administrator * Surfaceview只有當activity顯示到前台,該空間才會被創建 */ private final class MySurfaceCallback implements SurfaceHolder.Callback { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub try { // 當surfaceview創建就去打開相機 camera = Camera.open(); Camera.Parameters params = camera.getParameters(); // Log.i("i", params.flatten()); params.setJpegQuality(80); // 設置照片的質量 params.setPictureSize(1024, 768); params.setPreviewFrameRate(5); // 預覽幀率 camera.setParameters(params); // 將參數設置給相機 //右旋90度,將預覽調正 camera.setDisplayOrientation(90); // 設置預覽顯示 camera.setPreviewDisplay(surfaceview.getHolder()); // 開啟預覽 camera.startPreview(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub if(camera != null){ camera.release(); camera = null; } } } //拍照的函數 public void takepicture(){ /* * shutter:快門被按下 * raw:相機所捕獲的原始數據 * jpeg:相機處理的數據 */ camera.takePicture(null, null, new MyPictureCallback()); } //byte轉Bitmap public Bitmap Bytes2Bimap(byte[] b) { if (b.length != 0) { return BitmapFactory.decodeByteArray(b, 0, b.length); } else { return null; } } //bitmap轉byte public byte[] Bitmap2Bytes(Bitmap bm) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); return baos.toByteArray(); } //照片回調函數,其實是處理照片的 private final class MyPictureCallback implements Camera.PictureCallback { @Override public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub try { Bitmap bitmap = Bytes2Bimap(data); Matrix m = new Matrix(); int width = bitmap.getWidth(); int height = bitmap.getHeight(); m.setRotate(90); //將照片右旋90度 bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, true); Log.d("TAG","width "+width); Log.d("TAG","height "+height); //截取透明框內照片 bitmap = Bitmap.createBitmap(bitmap,50,250,650,500); data = Bitmap2Bytes(bitmap); File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); FileOutputStream fos = new FileOutputStream(file); fos.write(data); // 在拍照的時候相機是被占用的,拍照之後需要重新預覽 camera.startPreview(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
以上所述是小編給大家介紹的Android開發仿掃一掃實現拍攝框內的照片功能 ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對本站網站的支持!
首先引申下AIDL,什麼是AIDL呢?IPC? ------ Designing a Remote Interface Using AIDL 通常情況下,我們在同一進程內
View的Draw時序圖前面幾篇通過對View樹的measure和layout過程分析事,接下來將結合前兩步得到的測量值及在視圖中的位位置,開始進行繪制操作,一步比一步復
使用意圖篩選器 點擊下載源碼 1、創建一個Intents項目,給該項目添加一個新類,命名為MyBrowserActivity,在res/layout文件夾下
activity的啟動模式一共有四種:standard、singleTop、singleTask和singleInstance,可以在AndroidMannifest.x