XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2017/01/08

用 Xamarin.Forms 開發拍照與上傳照片的功能

這是有人提出的問題,想要使用 Visual Studio + Xamarin.Forms,開發出一個可以使用手機拍照的功能,並且可以將這個照片檔案,上傳到網路上;我剛剛寫了一個小的範例程式,底下的程式碼為這個拍照頁面的 ViewModel 程式碼。

了解更多關於 [Xamarin.Android] 的使用方式
了解更多關於 [Xamarin.iOS] 的使用方式
了解更多關於 [Xamarin.Forms] 的使用方式
了解更多關於 [Hello, Android:快速入門] 的使用方式
了解更多關於 [Hello, iOS – 快速入門] 的使用方式
了解更多關於 [Xamarin.Forms 快速入門] 的使用方式

想要使用拍照功能,您需要安裝這兩個 PCLStorage / Xam.Plugin.Media NuGet 套件。
其中,要進行拍照的時候,可以使用這個方法 CrossMedia.Current.TakePhotoAsync 來啟動手機中的照相機,一旦完成照相作業,就可以取得這個照片的檔案路徑。
而要將圖片上傳到遠端伺服器的工作,則使用了 .NET 裡面的 HttpClient 物件,當然,在 PCL 專案內您會找不到這個類別,請您要安裝 Microsoft.Net.Http 這個 NuGet 套件即可使用。
        public MainPageViewModel(IPageDialogService dialogService)
        {

            _dialogService = dialogService;
            拍照Command = new DelegateCommand(async () =>
            {
                // 進行 Plugin.Media 套件的初始化動作
                await CrossMedia.Current.Initialize();

                // 確認這個裝置是否具有拍照的功能
                if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
                {
                    await _dialogService.DisplayAlertAsync("No Camera", ":( No camera available.", "OK");
                    return;
                }

                // 啟動拍照功能,並且儲存到指定的路徑與檔案中
                var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
                {
                    Directory = "Sample",
                    Name = "Sample.jpg"
                });

                if (file == null)
                    return;

                // 讀取剛剛拍照的檔案內容,轉換成為 ImageSource,如此,就可以顯示到螢幕上了
                MyImageSource = ImageSource.FromStream(() =>
                {
                    var stream = file.GetStream();
                    return stream;
                });

                #region 將剛剛拍照的檔案,上傳到網路伺服器上
                using (var client = new HttpClient())
                {
                    using (var content = new MultipartFormDataContent())
                    {
                        // 取得這個圖片檔案的完整路徑
                        var path = file.Path;
                        // 取得這個檔案的最終檔案名稱
                        var filename = Path.GetFileName(path);

                        // 開啟這個圖片檔案,並且讀取其內容
                        using (var fs = file.GetStream())
                        {
                            var streamContent = new StreamContent(fs);
                            streamContent.Headers.Add("Content-Type", "application/octet-stream");
                            streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"" + Path.GetFileName(path) + "\"");
                            content.Add(streamContent, "file", filename);

                            // 上傳到遠端伺服器上
                            HttpResponseMessage message = await client.PostAsync("http://YourHost/api/UploadImage", content);
                            var input = message.Content.ReadAsStringAsync();
                            // 更新頁面上的 Image 控制項,顯示出剛剛上傳的圖片內容
                            RemoteImageURL = $"http://YourHost/uploads/{filename}";
                        }
                    }
                }
                #endregion

            });
        }

12 則留言:

  1. 大大,有没有http://YourHost 的源码?

    回覆刪除
  2. 建立一個 ASP.NET MVC 之 Web API,加入底下的 Post() 方法即可

    public string Post()
    {
    var file = HttpContext.Current.Request.Files.Count > 0 ? HttpContext.Current.Request.Files[0] : null;

    if (file != null && file.ContentLength > 0)
    {
    var fileName = Path.GetFileName(file.FileName);

    var path = Path.Combine(
    HttpContext.Current.Server.MapPath("~/Uploads"),
    fileName
    );

    file.SaveAs(path);
    }

    return file != null ? "/Uploads/" + file.FileName : "";


    }

    回覆刪除
  3. 大大,我有问题, 当我要上传照片时,出现这个Error.
    System.Net.ProtocolViolationException: The number of bytes to be written is greater than the specified ContentLength.

    回覆刪除
  4. 大大, 请问要如何写照片GET API ? 谢谢。

    回覆刪除
  5. 可以取得這個照片的 URL,直接在 XAML 中使用 Image 來設定 Source 屬性

    若要在 Xamarin.Forms 中下透過API下載圖片檔案到手機中,並且顯示已下載的圖片,可以參考這個範例

    https://github.com/vulcanlee/xamarin-forms-develop-notes-example/tree/master/XFImage

    回覆刪除
    回覆
    1. 当我拿到URL时, 我打开时是 “The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."

      刪除
    2. 我剛剛開啟這個網址,可以打開喔,
      您可以試看看這個 https://github.com/vulcanlee/xamarin-forms-develop-notes-example

      刪除
    3. 這是我剛剛打開網址的螢幕截圖
      https://www.screencast.com/t/58Xmbr0stK2g

      刪除
    4. 哎呀,放错地方回复。

      刪除
    5. 我打开URL(https://uploadserver.azurewebsites.net/api/Files/Uploads/IMG_20170208_155125.jpg)时是 “The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."

      刪除
    6. 這個Web服務 https://uploadserver.azurewebsites.net 是您自己開發的嗎?
      看樣子,似乎沒有這個圖片存在

      刪除
  6. 請問如果要在拍照時關閉拍照的音效可以如何撰寫呢?

    回覆刪除