0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Image.networkでGoogle Drive上の画像を取得しようとした話

Posted at

はじめに

現在作成しているアプリでGoogle Drive上の画像を読み込みたいと思い、実装してみたのですが問題発生。

        var url = "https://drive.google.com/uc?export=view&id=$fileId";
        var downloadImage = Image.network(url,
          headers: {
            "Authorization": "Bearer $accessToken"
          },
          loadingBuilder: (context, child, loadingProgress) {
            if(loadingProgress != null){
              return _noImage;
            }
            return child;
          },
          frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
            if(!wasSynchronouslyLoaded && frame == 0){
              // ロード完了
            }
            return child;
          },
          errorBuilder: (context, error, stackTrace) {
            return _noImage;
          },
        );

これを実行すると以下のエラーが発生する。

Exception: Invalid image data
             Exception: Invalid image data
             #0      _futurize (dart:ui/painting.dart:6637:5)
             #1      ImageDescriptor.encoded (dart:ui/painting.dart:6494:12)
             #2      instantiateImageCodecWithSize (dart:ui/painting.dart:2291:60)
             #3      PaintingBinding.instantiateImageCodecWithSize (package:flutter/src/painting/binding.dart:182:15)
             #4      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:153:22)
             <asynchronous suspension>

これを解決するのが今回のお話です。

Goodle Driveで提供されるURL

共有のURL

Google Driveで共有の際提供されるURLは

https://drive.google.com/file/d/{fileId}/view?usp=drive_link

になります。
このURLをChromeで確認するとこんな感じでいっぱい通信が行われます。
image.png

おそらくですが、共有で提供されるリンクでは、最初にHTTP Status 200で返却される内容がHTMLなので失敗すると予想されます。

ダウンロードのURL

では次にダウンロードで使用されるURLを確認します。
URLは以下の通りです。

https://drive.google.com/uc?export=view&id={fileId}

このURLをChromeで確認すると、複数の通信が発生していることがわかります。
image.png

ただ、リダイレクトされまくったあとの200のヘッダを見ると Content-Type:image/jpeg で返却されているので、よさそうに見えます。
しかし実際には Exception: Invalid image data が発生します。

対象画像の共有の設定を リンクを知っている全員 に変更すると表示されました。

認証情報を付与してリクエストできれば、共有設定を リンクを知っている人全員 にしなくても行けそうですが、手段がわからないので、現段階ではこれで行くしかない。

        var url = "https://drive.usercontent.google.com/uc?id=$fileId&export=download";
        var downloadImage = Image.network(url,
          headers: {
            "Authorization": "Bearer $accessToken"
          },
          loadingBuilder: (context, child, loadingProgress) {
            if(loadingProgress != null){
              return _noImage;
            }
            return child;
          },
          frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
            if(!wasSynchronouslyLoaded && frame == 0){
              // ロード完了
            }
            return child;
          },
          errorBuilder: (context, error, stackTrace) {
            return _noImage;
          },
        );

まとめ

  • Image.network で指定するURLはダウンロードで使用するURL
  • 画像の共有設定は リンクを知っている全員 にする
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?