Flutter Notes: アプリケーションでのアバターとしての写真の送信について

フラッターノート
アプリ内でのアバターとしての写真の送信について

著者: Li Juncai (jcLee95) : https://blog.csdn.net/qq_28550263
電子メール : [email protected]
記事アドレス: https://blog.csdn.net/qq_28550263/article/details/133418554



1. アバターの選択と提出の一般的な手順

Flutter アプリで画像をアバターとして送信するには、次の手順に従います。

  1. 画像を選択してください:
    • ユーザーに希望の画像を選択またはキャプチャさせます。Flutterのimage_pickerプラグインを利用して画像選択機能を実装できます。pubspec.yamlプラグインの依存関係をファイルに必ず追加してください。
flutter pub add image_picker

image_picker をインポートし、それを使用して画像を選択または取得します。

import 'package:image_picker/image_picker.dart';

// ...

final picker = ImagePicker();

// 从相册选择图像
final pickedFile = await picker.getImage(source: ImageSource.gallery);

// 或者拍摄新的照片
final pickedFile = await picker.getImage(source: ImageSource.camera);
  1. 画像をアップロード:

    • 選択した画像をサーバーまたはクラウド ストレージ サービスにアップロードして、ユーザーのアバターとして保存できるようにします。HTTP リクエストを使用して画像をアップロードすることも、クラウド ストレージ SDK (Firebase Storage、AWS S3 など) を使用して画像をアップロードすることもできます。
  2. 画像を処理します:

    • 画像が正常にアップロードされたら、サイズ変更やその他の編集を行う必要がある場合があります。imageFlutter は、さまざまな画像操作を実行するために使用できるライブラリなど、多くの画像処理ライブラリを提供します。
import 'package:image/image.dart' as img;

// 加载上传的图像
final image = img.decodeImage(uploadedImageData);

// 调整图像大小
final resizedImage = img.copyResize(image, width: 200, height: 200);

// 将处理后的图像保存到文件或云存储
img.encodePng(resizedImage); // 保存为PNG格式
  1. アバターを表示:
    • 加工した画像をユーザーのアバターとしてアプリケーションに表示します。ImageまたはImage.networkウィジェットを使用して画像をロードして表示できます。

      Image.memory(resizedImage); // 从内存中加载图像
      

これらの手順では、画像の選択からアップロード、処理、表示までの基本的なプロセスを説明します。特定のニーズとバックエンドの実装に基づいてこれらの手順をカスタマイズしてください。さらに、デバイス上のフォト アルバムまたはカメラにアクセスするための適切な権限がアプリにあることを確認してください。これには通常、AndroidManifest.xmlおよびファイルInfo.plistで権限を構成する必要があります。

2. ローカルファイルを選択してアバターのサンプルコードを作成します

以下のコードでは、ユーザーはアバター領域をクリックしてローカル画像をアバターとして選択できます。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
    
    
  const MyApp({
    
    super.key});

  
  Widget build(BuildContext context) {
    
    
    return const MaterialApp(
      home: ProfilePage(),
    );
  }
}

/// 个人资料页面的Flutter小部件。
class ProfilePage extends StatefulWidget {
    
    
  const ProfilePage({
    
    super.key});

  
  State<ProfilePage> createState() => _ProfilePageState();
}

/// 个人资料页面的状态类,负责管理页面上的用户头像和图像选择。
class _ProfilePageState extends State<ProfilePage> {
    
    
  File? _image; // 存储用户选择的图像文件

  /// 从图库选择图像并更新UI的异步方法。
  Future<void> _getImage() async {
    
    
    final picker = ImagePicker(); // 创建ImagePicker实例
    final pickedFile =
        await picker.pickImage(source: ImageSource.gallery); // 从图库中选择图像

    if (pickedFile != null) {
    
    
      setState(() {
    
    
        _image = File(pickedFile.path); // 将选定的图像文件赋给_image
      });
    }
  }

  
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      appBar: AppBar(
        title: const Text('个人资料'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            GestureDetector(
              onTap: _getImage, // 点击头像区域时触发_getImage方法
              child: CircleAvatar(
                radius: 80,
                backgroundImage: _image != null
                    ? FileImage(_image!)
                    : null, // 根据_image是否为空设置头像图片
                child: _image == null
                    ? const Icon(
                        Icons.camera_alt,
                        size: 80,
                        color: Colors.white,
                      )
                    : null,
              ),
            ),
            const SizedBox(height: 20),
            const Text(
              '点击头像选择图片',
              style: TextStyle(fontSize: 18),
            ),
          ],
        ),
      ),
    );
  }
}

効果は次のとおりです。

ここに画像の説明を挿入します
_ProfilePageState クラスで、ユーザーが選択した画像ファイルを保存するための _image という名前のファイル タイプ変数を作成します。

_ProfilePageState クラスで、_getImage という名前の非同期メソッドを作成します。このメソッドは、ImagePicker ライブラリを使用してデバイスのギャラリーから画像を選択し、選択した画像ファイルを _image 変数に保存します。

GestureDetector: 画像選択操作をトリガーするために使用されるクリック可能なウィジェット。ユーザーがアバター領域をクリックすると、_getImage メソッドが呼び出されます。
CircleAvatar: ユーザーのアバターを表示します。そのbackgroundImage属性は、_imageが空かどうかに応じてユーザーのアバター画像またはカメラアイコンを設定します。_image が空の場合、カメラ アイコンが表示され、ユーザーはそれをクリックして画像を選択できます。

効果の観点から:

  • ユーザーが最初にページを参照すると、アバター領域にカメラ アイコンが表示され、その下に「アバターをクリックして写真を選択してください」というテキストが表示されます。
  • ユーザーがアバター領域をクリックすると、_getImage メソッドがトリガーされ、ImagePicker ライブラリを使用してデバイス ギャラリーから画像ファイルを選択します。
  • 選択した画像ファイルは _image 変数に割り当てられ、setState がトリガーされて UI を再構築するように Flutter に通知します。
  • UIを構築する際、_imageの状態に応じて選択したユーザーアバターやカメラアイコンを表示します。

3. 画像をバックエンドに送信します

ユーザーが選択した画像を指定したインターフェイスに転送するには、HTTP リクエストを使用して画像ファイルをサーバーにアップロードします。Django では、この HTTP リクエストを処理し、画像を画像フィールドに保存するビュー関数を作成できます。一般的な手順は次のとおりです。

クライアント(Flutter)部分

画像を選択したら、ファイルとしてサーバーにアップロードします。

import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart'; // 用到其中的 lookupMimeType

// 在 _getImage 方法中上传图像
Future<void> _uploadImage() async {
    
    
  final url = Uri.parse('https://example.com/upload_image'); // 服务器接口地址
  final request = http.MultipartRequest('POST', url);
  request.files.add(
    await http.MultipartFile.fromPath(
      'image', // 后端接口中接受图像文件的字段名称
      _image!.path, // 图像文件的路径
      contentType: MediaType.parse(lookupMimeType(_image!.path) ?? 'image/jpeg'),
    ),
  );

  final response = await request.send();
  if (response.statusCode == 200) {
    
    
    print('图像上传成功');
  } else {
    
    
    print('图像上传失败');
  }
}

で:!
MIME ライブラリを使用すると、HTTP リクエストの Content-Type ヘッダーを正しく設定するためにファイルの MIME タイプを決定できます。サーバーは受信したデータを正しく処理するためにそのタイプを知る必要があるため、これはファイルのアップロードと処理の場合に特に重要です。参照してください: https://pub.dev/documentation/mime/latest/

lookupMimeTypeこの関数は、ファイル パスからファイルのMIMEタイプを抽出します。適切な MIME タイプが見つからない場合はimage/jpeg、デフォルトで画像ファイルの一般的なタイプであるMIME タイプが使用されます。このMIMEタイプは、サーバーがアップロードされた画像ファイルのタイプを正しく解釈できるようにするために、HTTPリクエストのヘッダーを設定するために使用されますContent-Typeこれにより、サーバーが画像データを正しく処理できるようになります。

バックエンド (Django を例に挙げます) 部分

Django バックエンドが user という名前のアプリを使用してユーザーを管理するとします。user/models.pyユーザーのアバターを保存するための単純なモデルを に定義しますDjango の組み込みを使用してImageField画像ファイルを処理します。コードは次のとおりです。

# user/models.py
from django.db import models

class UserProfile(models.Model):
    username = models.CharField(max_length=100)
    avatar = models.ImageField(upload_to='avatars/', blank=True, null=True)

    def __str__(self):
        return self.username

アプリケーションのファイルで、と がアップロードされた画像ファイルを処理するようにsettings.py構成されていることを確認してくださいMEDIA_URLMEDIA_ROOT

# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

ルートの割り当てに関しては、まずプロジェクトのルート urls.py にあるユーザー アプリケーションの「user.urls.py」にルートを割り当てることができますが、この手順は省略されています。

次に、アプリケーションのurls.pyファイルに、アップロードされた画像リクエストを処理する URL ルートを設定します。

# user/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('upload_avatar/', views.upload_avatar, name='upload_avatar'),
]

次に、新しいビュー ファイルを作成します。つまり、user/views.pyファイルを作成し、画像のアップロード リクエストを処理するビュー関数を作成します。

# user/views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def upload_avatar(request):
    if request.method == 'POST':
        uploaded_file = request.FILES['avatar']  # 头像图像文件字段的名称,与前端对应
        # 保存图像到用户的头像字段
        # 注意:这里需要根据你的模型来设置,这里仅供示例
        user_profile = UserProfile.objects.get(username=request.user.username)
        user_profile.avatar = uploaded_file
        user_profile.save()
        return JsonResponse({
    
    'message': '头像上传成功'})
    else:
        return JsonResponse({
    
    'message': '无效的请求'}, status=400)

移行して新しいモデルの変更を適用します。

python manage.py makemigrations
python manage.py migrate

そしてそれを/upload_avatar/URL に POST してアバターのアップロードを実行します。Django ローカル開発サーバーを使用してデフォルトで起動する場合は、「http://127.0.0.1:8000/user/upload_avatar/」をリクエストします。

このようにして、ユーザーが画像を選択し、メソッドがトリガーされると、画像はHTTP POST リクエストを介して_uploadImageDjango サーバーのビュー関数にアップロードされます。upload_imageビュー機能では、ビジネス ロジックに基づいて、モデルの画像フィールドまたはその他の必要な場所に画像を保存できます。その後、サーバーは、画像のアップロードが成功したかどうかをフロントエンドに伝える応答を返します。

おすすめ

転載: blog.csdn.net/qq_28550263/article/details/133418554