[Xamarin] 啟動拍照並且儲存 (转帖)
拍照對手機來說是很常用到的功能,許多App都基於在拍照上面,這篇文章主要大部分是在翻譯官方文件 (http://docs.xamarin.com/recipes/android/other_ux/camera_intent/take_a_picture_and_save_using_camera_app) 因為這篇寫得很清楚,主要我就筆記且翻譯一些比較重要的地方。
這篇文章主要聊聊如何啟動相機,並且拍一張照片之後,將照片取回來顯示在ImageView 上面
1. 首先我們看一下畫面,有一顆按鈕點下去後就啟動相機,並且將圖片帶回,首先你得先做幾件事情,開啟一個專案,再來就是新增AndroidManifest.xml 並且 新增WRITE_EXTERNAL_STORAG的權限。下面為 主要畫面的axml code :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/myButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="開啟照相機" />
<ImageView
android:src="@android:drawable/ic_menu_gallery"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/imageView1"
android:adjustViewBounds="true" />
</LinearLayout>
預覽:
![]()
2.接者,我在主要的Activity 中加入一些變數
Java.IO.File _file;
Java.IO.File _dir;
ImageView _imageView;
3.我們在OnCreate 中加入這些程式碼:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
if (IsThereAnAppToTakePictures())
{
CreateDirectoryForPictures();
Button button = FindViewById<Button>(Resource.Id.myButton);
_imageView = FindViewById<ImageView>(Resource.Id.imageView1);
button.Click += TakeAPicture;
}
}
會出現紅字別緊張還有兩個function沒有補上
/// <summary>
/// 判斷是否可以正常叫起相機
/// </summary>
/// <returns></returns>
private bool IsThereAnAppToTakePictures()
{
var intent = new Intent(MediaStore.ActionImageCapture);
IList<ResolveInfo> availableActivities = PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
return availableActivities != null && availableActivities.Count > 0;
}
/// <summary>
/// 在外部儲存裝置中建立起檔案夾並且使用當作暫存
/// </summary>
private void CreateDirectoryForPictures()
{
_dir = new File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures), "CameraAppDemo");
if (!_dir.Exists())
{
_dir.Mkdirs();
}
}
接下來,我們需要處理按鈕的Click事件。在這個例子中,我們將創建一個將處理事件的方法:
/// <summary>
/// 點擊拍照按鈕後啟動拍照
/// </summary>
/// <param name="sender"></param>
/// <param name="eventArgs"></param>
private void TakeAPicture(object sender, EventArgs eventArgs)
{
//使用intent 叫起拍照動作
var intent = new Intent(MediaStore.ActionImageCapture);
//回存的檔名
_file = new File(_dir, String.Format("myPhoto_{0}.jpg", Guid.NewGuid()));
intent.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(_file));
//等待結果的呼叫Activity
//可以參考 http://no2don.blogspot.com/2013/07/xamarin-startactivityforresult.html
StartActivityForResult(intent, 0);
}
當用戶點擊按鈕,該程式將會發送一個intent 要求android 來找到一個活動去拍照,通常是用系統現在指定的拍照軟體,請注意在intent中我們提供她儲存位置,再來我們看看當OnActivityResult 被觸發(因為使用的是StartActivityForResult)的程式碼實作:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
// 讓此可以在圖片庫中被使用
// 這一段不寫不會影響功能只是在圖片庫中,並不會顯示此張照片
var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
var contentUri = Android.Net.Uri.FromFile(_file);
mediaScanIntent.SetData(contentUri);
SendBroadcast(mediaScanIntent);
//
// 將其顯示在ImageView上面
// 因為避免拍照片太大導致app crash
int height = _imageView.Height;
int width = Resources.DisplayMetrics.WidthPixels;
//using (Bitmap bitmap = _file.Path.LoadAndResizeBitmap(width, height))
using (Bitmap bitmap = _file.Path.LoadAndResizeBitmap(width, height))
{
_imageView.SetImageBitmap(bitmap);
}
}
按照原文範例,為了避免App Crash 所以必須要調整大小,所以官方的教學文件上面附上一個BitmapHelper來作,請就直接開一個BitmapHelper.cs 來貼上下面的code:
using Android.Graphics;
namespace SampleOpenCamera
{
public static class BitmapHelpers
{
public static Bitmap LoadAndResizeBitmap(this string fileName, int width, int height)
{
// First we get the the dimensions of the file on disk
BitmapFactory.Options options = new BitmapFactory.Options { InJustDecodeBounds = true };
BitmapFactory.DecodeFile(fileName, options);
// Next we calculate the ratio that we need to resize the image by
// in order to fit the requested dimensions.
int outHeight = options.OutHeight;
int outWidth = options.OutWidth;
int inSampleSize = 1;
if (outHeight > height || outWidth > width)
{
inSampleSize = outWidth > outHeight
? outHeight / height
: outWidth / width;
}
// Now we will load the image and have BitmapFactory resize it for us.
options.InSampleSize = inSampleSize;
options.InJustDecodeBounds = false;
Bitmap resizedBitmap = BitmapFactory.DecodeFile(fileName, options);
return resizedBitmap;
}
}
}
結果 :
![]()
![]()
圖片存放位置: /storage/sdcard0/Pictures/CameraAppDemo
![]()
[Xamarin] 啟動拍照並且儲存 (转帖)的更多相关文章
- [Xamarin.Android] 儲存資料於Windows Azure (转帖)
在準備討論Xamarin.Android 如何整合GCM與Windows Azure來實作Push Notification之前, 先來了解如何將Xamarin.Android 與Windows Az ...
- [Xamarin] 透過 IsolatedStorageFile儲存資料(转帖)
開發手機App通常都會遇到想要儲存資料的,舉個例來說,像是 (圖片來源:http://docs.xamarin.com/guides/android/application_fundamentals/ ...
- 問題排查:F5啟動偵錯後所提示的錯誤 (2)
原始專案版本:Visual Studio 2005 開發環境:Visual Studio 2013 偵錯運行環境:IIS Express 啟動偵錯後,錯誤提示內容如下: HTTP 错误 403.14 ...
- 問題排查:F5啟動偵錯後所提示的錯誤 (1)
原始專案版本:Visual Studio 2005 開發環境:Visual Studio 2013 偵錯運行環境:IIS Express 啟動偵錯後,錯誤提示內容如下: HTTP 错误 500.23 ...
- [Xamarin] 關於發出Notification 的大小事 (转帖)
關於Anroid 的使用者來說,Notification 是一個非常會看到且用到的功能 他可以提醒使用者甚麼東西需要待處理,像是郵件或是會議的提醒等.. 甚至有些APP ,直接使用Notificati ...
- Visual Studio 跨平台開發實戰(4) - Xamarin Android 基本控制項介紹 (转帖)
前言 不同於iOS, Xamarin 在Visual Studio中針對Android, 可以直接設計使用者介面. 在本篇教學文章中, 筆者會針對Android的專案目錄結構以及基本控制項進行介紹, ...
- [Xamarin] 製作吐司(Toast)以及圖文並茂的Toast (转帖)
最近在看Xamarin使用C#來撰寫Android App . 紀錄一下,順便給之後有需要的人可以有所參考 :) 今天要來聊的是關於Toast 這東西,這在以前Android 上面我是很常使用 拿來l ...
- [CentOS 6.5 X64]讓firefox java plugin 啟動
到ORACLE下載JRE http://www.oracle.com/technetwork/java/javase/downloads/index.html 我是X64所以下載 jre-7-linu ...
- xamarin android打开拍照
xamarin android打开摄像头 Intent intentBrowser = new Intent("android.media.action.IMAGE_CAPTURE" ...
随机推荐
- java并发编程_CountDownLanch(倒计数锁存器)应用场景
使用介绍: 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown() 方法,所以在 ...
- Shell_参数替换(転)
From: http://www.cnblogs.com/yjf512/archive/2013/06/03/3114803.html Bash中的$符号的作用是参数替换,将参数名替换为参数所代表的值 ...
- 进阶篇:以IL为剑,直指async/await
接上篇:30分钟?不需要,轻松读懂IL,这篇主要从IL入手来理解async/await的工作原理. 先简单介绍下async/await,这是.net 4.5引入的语法糖,配合Task使用可以非常优雅的 ...
- nginx 命令
nginx 命令 sudo /etc/init.d/nginx configtest 测试是否配置有错 sudo /usr/local/nginx/sbin/nginx -s reload ...
- Linux驱动框架之framebuffer驱动框架
1.什么是framebuffer? (1)framebuffer帧缓冲(一屏幕数据)(简称fb)是linux内核中虚拟出的一个设备,framebuffer向应用层提供一个统一标准接口的显示设备.帧缓冲 ...
- UNIX环境高级编程--10. 信号
第十章 信号 信号是软中断,提供了一种处理异步事件的方法.例如,终端用户键入终端键,会通过信号机制停止一个进程,或及早终止管道中的下一个程序. 每个信号都有一个名字,SIG开 ...
- [原创] Legato 8.1 oracle full backup skip 奇怪的问题处理过程 -- 非调度日期手工运行调度也不成功(skip)
转载请注明出处: http://www.cnblogs.com/fengaix6/p/4677024.html 作者:飄ぺ風 环境: a. Server: Legato 8.1.2, aix 6.1 ...
- WCF三种通信模式
WCF在通信过程中有三种模式:请求与答复.单向.双工通信. 请求与答复模式 描述:客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务端有了答复后才能继续执行其他程序 ...
- Java关键字:transient,strictfp和volatile简介
关键字:transient 使用对象:字段 介绍:transient说明一个属性是临时的,不会被序列化. 当对象进行序列化(Serializable)过程时候,有一些属性的状态是瞬时的,这样的对象是无 ...
- Nodejs编码转化问题
目前Node.js仅支持hex.utf8.ascii.binary.base64.ucs2几种编码的转换.对于GBK,GB2312等编码,Nodejs自带的toString()方法不支持,因此中文转化 ...