ورود و عضویت
0
سبد خرید شما خالی است
0
سبد خرید شما خالی است

آموزش استفاده از دوربین در برنامه نویسی فلاتر

2 دیدگاه
Flutter

امروزه دوربین یکی از امکانات مهم گوشی های هوشمند به شمار می رود و کاربران زیادی روزانه از طریق موبایل عکس و فیلم تهیه میکنند.

در دنیای برنامه‌نویسی موبایل، نیاز به استفاده از دوربین در برنامه‌های مختلف به وضوح احساس می‌شود. فلاتر به عنوان یک چارچوب محبوب برای توسعه اپلیکیشن‌های موبایل، امکانات قدرتمندی را برای کار با دوربین ارائه می‌دهد.

در این مطلب با همدیگه یاد میگیریم تا چجوری از دوربین جلو و عقب گوشی های موبایل در برنامه نویسی Flutter استفاده کنیم.

در حالت برای استفاده از دوربین باید از زبان جاوا یا کاتلین استفاده میکردیم و یک SurfaceView میساختیم پیش نمایش تصاویر دریافتی از دوربین را مشاهده کنیم.

همچنین برای آیفون هم از زبان و سویفت و AVFoundation Capture کمک میگرفتیم.

اما با استفاده از فلاتر فقط با یکبار برنامه نویسی در هر دو سیستم عامل این امکانات را استفاده میکنیم که فوق العاده است.

کاربرد دوربین در برنامه نویسی اپلیکیشن

امروزه دوربین به یکی از اجزای اصلی گوشی‌های هوشمند تبدیل شده است و کاربران به طور روزانه از آن برای عکس‌برداری، فیلم‌برداری و انجام وظایف مختلف استفاده می‌کنند.

در دنیای برنامه‌نویسی موبایل نیز، نیاز به استفاده از دوربین در برنامه‌های مختلف به وضوح احساس می‌شود.

کاربردهای دوربین در برنامه‌های موبایل بسیار متنوع هستند. برخی از رایج‌ترین کاربردهای دوربین در برنامه‌ها عبارتند از:

  • ثبت تصاویر و فیلم‌ها: برنامه‌های دوربین به کاربران امکان می‌دهند تا از محیط اطراف خود عکس و فیلم بگیرند.
  • اسکن بارکد و QR Code: برنامه‌های مختلفی برای اسکن بارکد و QR Code وجود دارند که از دوربین برای این منظور استفاده می‌کنند.
  • تشخیص چهره: برخی برنامه‌ها از دوربین برای تشخیص چهره افراد و احراز هویت آنها استفاده می‌کنند.
  • واقعیت افزوده: برنامه‌های واقعیت افزوده از دوربین برای ترکیب دنیای واقعی با دنیای مجازی استفاده می‌کنند.
  • آموزش: برنامه‌های آموزشی می‌توانند از دوربین برای نمایش تصاویر و فیلم‌های آموزشی به صورت زنده استفاده کنند.
  • پزشکی: برنامه‌های پزشکی می‌توانند از دوربین برای معاینه بیماران از راه دور استفاده کنند.

علاوه بر موارد ذکر شده، از دوربین می‌توان در برنامه‌های مختلف دیگری نیز استفاده کرد.

مزایای استفاده از دوربین در برنامه‌های موبایل:

  • افزایش جذابیت و کارایی برنامه: استفاده از دوربین می‌تواند برنامه‌ها را جذاب‌تر و کارآمدتر کند.
  • ارائه خدمات جدید و نوآورانه: با استفاده از دوربین می‌توان خدمات جدید و نوآورانه‌ای به کاربران ارائه داد.
  • افزایش تعامل کاربران با برنامه: استفاده از دوربین می‌تواند تعامل کاربران با برنامه را افزایش دهد.

کار با دوربین در فلاتر

در این آموزش از پکیج camera  که توسط تیم فلاتر توسعه داده شده استفاده میکنیم تا یک اپلیکیشن طراحی کنیم که کاربر بتونه بین دوربین جلو و عقب انتخاب کنه و پیش نمایش دوربین و ببینه سپس با گرفتن عکس در مسیر مشخصی آن را ذخیره کند و با دوستانش به اشتراک بگذارد.

برای شروع کار نیاز به 5 تا پکیج مختلف داریم.

camera: برای کار کردن با دوربین از این کتابخونه استفاده میکنیم.

path_provider: برای انتخاب مسیر ذخیره سازی عکس و فیلم.

video_player: برای نمایش ویدیو

esys_flutter_share: اشتراک گزاری ویدیو و عکس با دیگران

thumbnails: برای ساختن تصویر بند انگشتی از ویدیو

 
dependencies:
  camera:
  path_provider:
  thumbnails:
    git:
      url: https://github.com/divyanshub024/Flutter_Thumbnails.git
  video_player:
  esys_flutter_share:


حالا وارد فایل ios/Runner/Info.plist شوید و دستورات زیر را قرار دهید.

فلاتر

برای شروع ما باید لیست دوربین های گوشی را دریافت کنیم که از کد زیر استفاده میکنیم.

 
List<CameraDescription> _cameras;
@override
void initState() {
  _initCamera();
  super.initState();
}
Future<void> _initCamera() async {
  _cameras = await availableCameras();
}


در مرحله بعدی یک CameraController بسازیم و آنرا مقداردهی کنیم.

همانطور که از نامش پیداست کار کنترل دوربین گوشی را با CameraController انجام می دهیم.

CameraController دو ویژگی مهم دارد به نام های CameraDescription و ResolutionPreset.

برای CameraDescription مقدار _camera[0] را قرار میدیم که به معنی دوربین اصلی یا دوربین پشت گوشی می باشد و ResolutionPreset را برابر مدیوم میذاریم باشه.

CameraController _controller;

Future<void> _initCamera() async {
  _controller = CameraController(_cameras[0], ResolutionPreset.medium);
  _controller.initialize().then((_) {
    if (!mounted) {
      return;
    }
    setState(() {});
  });
}

@override
void dispose() {
  _controller?.dispose();
  super.dispose();
}

تا به اینجا کار تنظیمات دوربین را انجام داده ایم و وقت آن رسیده که بتونیم پیش نمایش تصاویر دوربین را در اپلیکیشن خودمون نمایش دهیم.

برای این کار از ویجتی به اسم CameraPreview استفاده میکنیم.

قبل از نشان دادن پیش نمایش ما باید صبر کنیم تا CameraController مقداری دهی شود.

@override
Widget build(BuildContext context) {
  if (_controller != null) {
    if (!_controller.value.isInitialized) {
      return Container();
    }
  } else {
    return const Center(
      child: SizedBox(
        width: 32,
        height: 32,
        child: CircularProgressIndicator(),
      ),
    );
  }
}

بعد از انجام شدن کد بالا, برای استفاده از پیش نمایش دوربین به شکل زیر عمل میکنیم.

 return Scaffold(
  backgroundColor: Theme.of(context).backgroundColor,
  key: _scaffoldKey,
  extendBody: true,
  body: Stack(
    children: <Widget>[
      _buildCameraPreview(),
    ],
  ),
);

در کد بالا از یک متد استفاده کردیم به اسم _buildCameraPreview() که در پایین آن را برنامه نویسی میکنیم.

در این متد پیش نمایش دوربین را بصورت تمام صفحه تعریف کرده ایم.

Widget _buildCameraPreview() {
  final size = MediaQuery.of(context).size;
  return ClipRect(
    child: Container(
      child: Transform.scale(
        scale: _controller.value.aspectRatio / size.aspectRatio,
        child: Center(
          child: AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            child: CameraPreview(_controller),
          ),
        ),
      ),
    ),
  );
}

قدم بعدی که میخواهیم برداریم اضافه کردن قابلیت جا به جایی بین دوربین های گوشی است.

مدیریت state فلاتر

برای این کار ابتدا یک آیکون درون ویجت Stack قرار میدیم.

body: Stack(
  children: <Widget>[
    _buildCameraPreview(),
    Positioned(
      top: 24.0,
      left: 12.0,
      child: IconButton(
        icon: Icon(
          Icons.switch_camera,
          color: Colors.white,
        ),
        onPressed: _onCameraSwitch,
      ),
    ),
  ],
),

با کلیک کردن روی آیکون متد _onCameraSwitch فراخوانی می شود.

در این متد CameraController قبلی و پاک میکنیم و با اطلاعات جدید که شامل CameraDescription است آنرا مقداردهی میکنیم.

 
Future<void> _onCameraSwitch() async {
  final CameraDescription cameraDescription =
      (_controller.description == _cameras[0]) ? _cameras[1] : _cameras[0];
  if (_controller != null) {
    await _controller.dispose();
  }
  _controller = CameraController(cameraDescription, ResolutionPreset.medium);
  _controller.addListener(() {
    if (mounted) setState(() {});
    if (_controller.value.hasError) {
      showInSnackBar('Camera error ${_controller.value.errorDescription}');
    }
  });

  try {
    await _controller.initialize();
  } on CameraException catch (e) {
    _showCameraException(e);
  }

  if (mounted) {
    setState(() {});
  }
}


در پایین صفحه برای کنترل کردن ویو های خودمون از سه تا آیکون استفاده میکنیم که در تصویر دمو بالای صفحه مشاهده کردید.

آیکون اول وارد گالری می شودی, آیکون دوم ثبت تصویر و ویدیو و آیکون سوم بین گرفتن عکس و فیلم جا به جا می شود.

return Scaffold(
  backgroundColor: Theme.of(context).backgroundColor,
  key: _scaffoldKey,
  extendBody: true,
  body: ...
  bottomNavigationBar: _buildBottomNavigationBar(),
);

پیاده سازی آیکون های پایین صفحه را در متدی به نام bottomNavigationBar انجام میدهیم.

 
Widget _buildBottomNavigationBar() {
  return Container(
    color: Theme.of(context).bottomAppBarColor,
    height: 100.0,
    width: double.infinity,
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: <Widget>[
        FutureBuilder(
          future: getLastImage(),
          builder: (context, snapshot) {
            if (snapshot.data == null) {
              return Container(
                width: 40.0,
                height: 40.0,
              );
            }
            return GestureDetector(
              onTap: () => Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => Gallery(),
                ),
              ),
              child: Container(
                width: 40.0,
                height: 40.0,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(4.0),
                  child: Image.file(
                    snapshot.data,
                    fit: BoxFit.cover,
                  ),
                ),
              ),
            );
          },
        ),
        CircleAvatar(
          backgroundColor: Colors.white,
          radius: 28.0,
          child: IconButton(
            icon: Icon(
              (_isRecordingMode)
                  ? (_isRecording) ? Icons.stop : Icons.videocam
                  : Icons.camera_alt,
              size: 28.0,
              color: (_isRecording) ? Colors.red : Colors.black,
            ),
            onPressed: () {
              if (!_isRecordingMode) {
                _captureImage();
              } else {
                if (_isRecording) {
                  stopVideoRecording();
                } else {
                  startVideoRecording();
                }
              }
            },
          ),
        ),
        IconButton(
          icon: Icon(
            (_isRecordingMode) ? Icons.camera_alt : Icons.videocam,
            color: Colors.white,
          ),
          onPressed: () {
            setState(() {
              _isRecordingMode = !_isRecordingMode;
            });
          },
        ),
      ],
    ),
  );
}


حالا نوبت به عکس گرفتن شده.

برای این کار ما سه مرحله و انجام میدیم.

اول: چک میکنیم ببینیم camera controller مقداردهی شده یا نه.

دوم: ساختن یک پوشه و مشخص کردن مسیر ذخیره شدن تصویر.

سوم: گرفتن عکس با استفاده از CameraController و ذخیره در مسیر مشخص شده.

void _captureImage() async {
  if (_controller.value.isInitialized) {
    final Directory extDir = await getApplicationDocumentsDirectory();
    final String dirPath = '${extDir.path}/media';
    await Directory(dirPath).create(recursive: true);
    final String filePath = '$dirPath/${_timestamp()}.jpeg';
    await _controller.takePicture(filePath);
    setState(() {});
  }
}

برای ضبط ویدیو نیز در 4 مرحله این کار و انجام میدهیم.

اول: چک میکنیم ببینیم camera controller مقداردهی شده یا نه.

دوم: نمایش تایمر برای نشان دادن مدت زمان ویدیو.

سوم: مشخص کردن مسیر ذخیره سازی ویدیو.

چهارم: استفاده از camera controller برای ضبط ویدیو و ذخیره کردن.

 
Future<String> startVideoRecording() async {
  print('startVideoRecording');
  if (!_controller.value.isInitialized) {
    return null;
  }
  setState(() {
    _isRecording = true;
  });
  _timerKey.currentState.startTimer();

  final Directory extDir = await getApplicationDocumentsDirectory();
  final String dirPath = '${extDir.path}/media';
  await Directory(dirPath).create(recursive: true);
  final String filePath = '$dirPath/${_timestamp()}.mp4';

  if (_controller.value.isRecordingVideo) {
    // A recording is already started, do nothing.
    return null;
  }

  try {
    await _controller.startVideoRecording(filePath);
  } on CameraException catch (e) {
    _showCameraException(e);
    return null;
  }
  return filePath;
}


حالا ما باید عملیات قطع کردن ضبط ویدیو را نیز پیاده سازی کنیم.

برای اینکار اول چک میکنیم که camera controller مقدار دهی شده باشه و سپس عملیات ضبط کردن و تامیر را غیر فعال میکنیم.

 
Future<void> stopVideoRecording() async {
  if (!_controller.value.isRecordingVideo) {
    return null;
  }
  _timerKey.currentState.stopTimer();
  setState(() {
    _isRecording = false;
  });

  try {
    await _controller.stopVideoRecording();
  } on CameraException catch (e) {
    _showCameraException(e);
    return null;
  }
}


کد های کامل صفحه اصلی بصورت زیر می باشد.

 
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_camera/gallery.dart';
import 'package:flutter_camera/video_timer.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:thumbnails/thumbnails.dart';

class CameraScreen extends StatefulWidget {
  const CameraScreen({Key key}) : super(key: key);

  @override
  CameraScreenState createState() => CameraScreenState();
}

class CameraScreenState extends State<CameraScreen>
    with AutomaticKeepAliveClientMixin {
  CameraController _controller;
  List<CameraDescription> _cameras;
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  bool _isRecordingMode = false;
  bool _isRecording = false;
  final _timerKey = GlobalKey<VideoTimerState>();

  @override
  void initState() {
    _initCamera();
    super.initState();
  }

  Future<void> _initCamera() async {
    _cameras = await availableCameras();
    _controller = CameraController(_cameras[0], ResolutionPreset.medium);
    _controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    if (_controller != null) {
      if (!_controller.value.isInitialized) {
        return Container();
      }
    } else {
      return const Center(
        child: SizedBox(
          width: 32,
          height: 32,
          child: CircularProgressIndicator(),
        ),
      );
    }

    if (!_controller.value.isInitialized) {
      return Container();
    }
    return Scaffold(
      backgroundColor: Theme.of(context).backgroundColor,
      key: _scaffoldKey,
      extendBody: true,
      body: Stack(
        children: <Widget>[
          _buildCameraPreview(),
          Positioned(
            top: 24.0,
            left: 12.0,
            child: IconButton(
              icon: Icon(
                Icons.switch_camera,
                color: Colors.white,
              ),
              onPressed: () {
                _onCameraSwitch();
              },
            ),
          ),
          if (_isRecordingMode)
            Positioned(
              left: 0,
              right: 0,
              top: 32.0,
              child: VideoTimer(
                key: _timerKey,
              ),
            )
        ],
      ),
      bottomNavigationBar: _buildBottomNavigationBar(),
    );
  }

  Widget _buildCameraPreview() {
    final size = MediaQuery.of(context).size;
    return ClipRect(
      child: Container(
        child: Transform.scale(
          scale: _controller.value.aspectRatio / size.aspectRatio,
          child: Center(
            child: AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              child: CameraPreview(_controller),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildBottomNavigationBar() {
    return Container(
      color: Theme.of(context).bottomAppBarColor,
      height: 100.0,
      width: double.infinity,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          FutureBuilder(
            future: getLastImage(),
            builder: (context, snapshot) {
              if (snapshot.data == null) {
                return Container(
                  width: 40.0,
                  height: 40.0,
                );
              }
              return GestureDetector(
                onTap: () => Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => Gallery(),
                  ),
                ),
                child: Container(
                  width: 40.0,
                  height: 40.0,
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(4.0),
                    child: Image.file(
                      snapshot.data,
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
              );
            },
          ),
          CircleAvatar(
            backgroundColor: Colors.white,
            radius: 28.0,
            child: IconButton(
              icon: Icon(
                (_isRecordingMode)
                    ? (_isRecording) ? Icons.stop : Icons.videocam
                    : Icons.camera_alt,
                size: 28.0,
                color: (_isRecording) ? Colors.red : Colors.black,
              ),
              onPressed: () {
                if (!_isRecordingMode) {
                  _captureImage();
                } else {
                  if (_isRecording) {
                    stopVideoRecording();
                  } else {
                    startVideoRecording();
                  }
                }
              },
            ),
          ),
          IconButton(
            icon: Icon(
              (_isRecordingMode) ? Icons.camera_alt : Icons.videocam,
              color: Colors.white,
            ),
            onPressed: () {
              setState(() {
                _isRecordingMode = !_isRecordingMode;
              });
            },
          ),
        ],
      ),
    );
  }

  Future<FileSystemEntity> getLastImage() async {
    final Directory extDir = await getApplicationDocumentsDirectory();
    final String dirPath = '${extDir.path}/media';
    final myDir = Directory(dirPath);
    List<FileSystemEntity> _images;
    _images = myDir.listSync(recursive: true, followLinks: false);
    _images.sort((a, b) {
      return b.path.compareTo(a.path);
    });
    var lastFile = _images[0];
    var extension = path.extension(lastFile.path);
    if (extension == '.jpeg') {
      return lastFile;
    } else {
      String thumb = await Thumbnails.getThumbnail(
          videoFile: lastFile.path, imageType: ThumbFormat.PNG, quality: 30);
      return File(thumb);
    }
  }

  Future<void> _onCameraSwitch() async {
    final CameraDescription cameraDescription =
        (_controller.description == _cameras[0]) ? _cameras[1] : _cameras[0];
    if (_controller != null) {
      await _controller.dispose();
    }
    _controller = CameraController(cameraDescription, ResolutionPreset.medium);
    _controller.addListener(() {
      if (mounted) setState(() {});
      if (_controller.value.hasError) {
        showInSnackBar('Camera error ${_controller.value.errorDescription}');
      }
    });

    try {
      await _controller.initialize();
    } on CameraException catch (e) {
      _showCameraException(e);
    }

    if (mounted) {
      setState(() {});
    }
  }

  void _captureImage() async {
    print('_captureImage');
    if (_controller.value.isInitialized) {
      SystemSound.play(SystemSoundType.click);
      final Directory extDir = await getApplicationDocumentsDirectory();
      final String dirPath = '${extDir.path}/media';
      await Directory(dirPath).create(recursive: true);
      final String filePath = '$dirPath/${_timestamp()}.jpeg';
      print('path: $filePath');
      await _controller.takePicture(filePath);
      setState(() {});
    }
  }

  Future<String> startVideoRecording() async {
    print('startVideoRecording');
    if (!_controller.value.isInitialized) {
      return null;
    }
    setState(() {
      _isRecording = true;
    });
    _timerKey.currentState.startTimer();

    final Directory extDir = await getApplicationDocumentsDirectory();
    final String dirPath = '${extDir.path}/media';
    await Directory(dirPath).create(recursive: true);
    final String filePath = '$dirPath/${_timestamp()}.mp4';

    if (_controller.value.isRecordingVideo) {
      // A recording is already started, do nothing.
      return null;
    }

    try {
//      videoPath = filePath;
      await _controller.startVideoRecording(filePath);
    } on CameraException catch (e) {
      _showCameraException(e);
      return null;
    }
    return filePath;
  }

  Future<void> stopVideoRecording() async {
    if (!_controller.value.isRecordingVideo) {
      return null;
    }
    _timerKey.currentState.stopTimer();
    setState(() {
      _isRecording = false;
    });

    try {
      await _controller.stopVideoRecording();
    } on CameraException catch (e) {
      _showCameraException(e);
      return null;
    }
  }

  String _timestamp() => DateTime.now().millisecondsSinceEpoch.toString();

  void _showCameraException(CameraException e) {
    logError(e.code, e.description);
    showInSnackBar('Error: ${e.code}\n${e.description}');
  }

  void showInSnackBar(String message) {
    _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
  }

  void logError(String code, String message) =>
      print('Error: $code\nError Message: $message');

  @override
  bool get wantKeepAlive => true;
}


بخش ثبت تصویر و ویدیو را تکمیل کردیم و نوبت به آن رسیده که بتونیم این تصاویر ثبت شده را از طریق گالری مشاهده کنیم.

برای ساخت گالری از یک pageview به صورت افقی به همراه دو آیکون برای پاک کردن تصویر و به اشتراک گزاری در پایین صفحه استفاده میکنیم.

درون بدنه PageView.builder ابتدا فرمت فایل ها را چک میکنیم.

اگر پسوند به صورت jpeg بود آن را به عنوان عکس نمایش میدهیم.

در حالت دیگر ویدیو ها را با استفاده از VideoPreview نمایش میدهیم.

 
String currentFilePath;
@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Theme.of(context).backgroundColor,
    appBar: AppBar(
      backgroundColor: Colors.black,
    ),
    body: FutureBuilder(
      future: _getAllImages(),
      builder: (context, AsyncSnapshot<List<FileSystemEntity>> snapshot) {
        if (!snapshot.hasData || snapshot.data.isEmpty) {
          return Container();
        }
        print('${snapshot.data.length} ${snapshot.data}');
        if (snapshot.data.length == 0) {
          return Center(
            child: Text('No images found.'),
          );
        }

        return PageView.builder(
          itemCount: snapshot.data.length,
          itemBuilder: (context, index) {
            currentFilePath = snapshot.data[index].path;
            var extension = path.extension(snapshot.data[index].path);
            if (extension == '.jpeg') {
              return Container(
                height: 300,
                padding: const EdgeInsets.only(bottom: 8.0),
                child: Image.file(
                  File(snapshot.data[index].path),
                ),
              );
            } else {
              return VideoPreview(
                videoPath: snapshot.data[index].path,
              );
            }
          },
        );
      },
    ),
    bottomNavigationBar: BottomAppBar(
      child: Container(
        height: 56.0,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            IconButton(
              icon: Icon(Icons.share),
              onPressed: () => _shareFile(),
            ),
            IconButton(
              icon: Icon(Icons.delete),
              onPressed: _deleteFile,
            ),
          ],
        ),
      ),
    ),
  );
}


دریافت فایل ها از طریق کد زیر انجام می شود.

 
Future<List<FileSystemEntity>> _getAllImages() async {
  final Directory extDir = await getApplicationDocumentsDirectory();
  final String dirPath = '${extDir.path}/media';
  final myDir = Directory(dirPath);
  List<FileSystemEntity> _images;
  _images = myDir.listSync(recursive: true, followLinks: false);
  _images.sort((a, b) {
    return b.path.compareTo(a.path);
  });
  return _images;
}


پاک کردن محتویات های گالری بسیار راحت است. فقط کافیست مسیر فایل را مشخص کنیم و سپس از deleteSync استفاده کنیم.

 
_deleteFile() {
  final dir = Directory(currentFilePath);
  dir.deleteSync(recursive: true);
  setState(() {});
}


برای اشتراک گزاری فایل ها از افزونه esys_flutter_share استفاده میکنیم.

به راحتی با دستور Share.file() عملیات اشتراک گزاری را انجام میدهیم.

این دستور شامل پارامتری های ورودی مانند نام,عنوان, لیستی از بایت ها می باشد.

 
_shareFile() async {
  var extension = path.extension(currentFilePath);
  await Share.file(
    'image',
    (extension == '.jpeg') ? 'image.jpeg' : '  video.mp4',
    File(currentFilePath).readAsBytesSync(),
    (extension == '.jpeg') ? 'image/jpeg' : '  video/mp4',
  );
}


کار ما در این پروژه به پایان رسید و امیدوارم که این آموزش برای شما برنامه نویسان مفید بوده باشه.

2 پاسخ به “آموزش استفاده از دوربین در برنامه نویسی فلاتر”

  1. علی گفت:

    سلام نوع نگارش تون خوبه اما من که نتونستم با استفاده از این آموزش پیاده سازی کنم کار رو.
    چون در خصوص lib نام شون و .. توضیحی نبود که فایل چگونه ایجاد بشه. من همین رو به علاوه دانش قبلی خودم تکمیل کردم 34 تا ارور داده..

    • Hesam گفت:

      سلام
      اسم و لینک کتابخونه های مورد استفاده داخل آموزش قرار داده شده است. در کدوم بخش مشکل دارید؟

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

Hesam
28 دسامبر 2019
آموزش فارسی فلاتر
آموزش فارسی flutter