Flutter Tutorial Membuat Camera Full Screen

Flutter Tutorial Membuat Camera Full Screen

Sobatcoding.com - Tutorial Membuat Kamera Full Screen Menggunakan Flutter

Pada artikel kali ini kita akan membuat aplikasi android berupa camera kemudian menampilkan preview dan upload photo. Hasil upload nanti akan kita simpan ke database menggunakan API.

Langsung saja kita buat, dan perhatikan step-step berikut.

 

Membuat Project Baru dan Install Dependencies

Kita buat terlebih dahulu project baru dengan nama appcamera atau nama sesuai yang kalian inginkan. Kemudian kita install juga beberapa dependencies yang nanti digunakan yaitu camera dan http. Gunakan command berikut untuk install dependencies nya.

flutter pub add camera
flutter pub add http

 

Untuk project kali ini menggunakan sdk min 30, kalian bisa ubah dengan cara buka file android/app/build.gradle

android {
    compileSdkVersion 30 //..ubah sesuai versi kalian inginkan

 

Membuat Camera View

Pada file main.dart masukkan kode berikut.

import 'package:flutter/material.dart';
import 'camera.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Camera'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
                onPressed: () => Navigator.push(context,
                    MaterialPageRoute(builder: (_) => const CameraPage())),
                child: const Text("Camera"))
          ],
        ),
      ),
    );
  }
}

Pada main.dart kita buat sebuah tombol yang apabila diklik akan mengarahkan ke halaman camera. Kemudian kita buat camera view dan masukkan code seperti berikut.

import 'package:camera/camera.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:appcamera/preview.dart';
import 'dart:math' as math;
import 'main.dart';

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

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

class _CameraState extends State<CameraPage> {
  CameraController? cameraController;
  List? cameras;
  int? selectedCameraIndex;

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

    availableCameras().then((value) {
      cameras = value;
      if (cameras!.isNotEmpty) {
        selectedCameraIndex = 0;
        initCamera(cameras![selectedCameraIndex!]).then((_) {});
      } else {
        debugPrint("Tidak ada kamera");
      }
    }).catchError((e) {
      debugPrint(e);
    });
  }

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

  Future initCamera(CameraDescription cameraDescription) async {
    if (cameraController != null) {
      await cameraController!.dispose();
    }

    cameraController =
        CameraController(cameraDescription, ResolutionPreset.high);
    cameraController!.addListener(() {
      if (mounted) {
        setState(() {});
      }
    });

    if (cameraController!.value.hasError) {
      debugPrint("Kamera Error");
    }

    try {
      await cameraController!.initialize();
    } catch (e) {
      debugPrint("kamera error $e");
    }
    if (mounted) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.black,
        body: Container(
          color: Colors.black,
          child: Stack(
            children: [
              Align(
                alignment: Alignment.center,
                child: cameraPreview(),
              ),
              Align(
                alignment: Alignment.bottomCenter,
                child: Container(
                  height: 120,
                  width: double.infinity,
                  padding: const EdgeInsets.all(15),
                  margin: const EdgeInsets.only(bottom: 20),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      backButton(),
                      const Spacer(),
                      cameraControl(context),
                      const Spacer(),
                      cameraToogle(),
                    ],
                  ),
                ),
              )
            ],
          ),
        ));
  }

  Widget backButton() {
    return FloatingActionButton(
      heroTag: null,
      onPressed: () => Navigator.push(
          context,
          MaterialPageRoute(
              builder: (_) => const MyHomePage(title: 'Flutter Demo Camera'))),
      child: const Icon(Icons.chevron_left),
      backgroundColor: Colors.black,
    );
  }

  Widget cameraPreview() {
    if (cameraController == null || !cameraController!.value.isInitialized) {
      return const Text("Loading ..");
    }
    /*return MaterialApp(
      home: CameraPreview(cameraController!),
    );*/
    final size = MediaQuery.of(context).size;
    var scale = size.aspectRatio * cameraController!.value.aspectRatio;
    if (scale < 1) scale = 1 / scale;
    final double mirror = selectedCameraIndex == 1 ? math.pi : 0;

    return Transform(
      alignment: Alignment.center,
      transform: Matrix4.rotationY(mirror),
      child: Transform.scale(
        scale: scale,
        child: Center(
          child: CameraPreview(cameraController!),
        ),
      ),
    );
  }

  Widget cameraToogle() {
    if (cameras == null || cameras!.isEmpty) {
      return const Spacer();
    }

    CameraDescription selectedCamera = cameras![selectedCameraIndex!];
    CameraLensDirection lensDirection = selectedCamera.lensDirection;

    return Expanded(
        child: Align(
      alignment: Alignment.center,
      child: FloatingActionButton(
        heroTag: null,
        onPressed: () {
          onSwitchCamera();
        },
        child: Icon(getCameraLensIcon(lensDirection),
            color: Colors.white, size: 24),
        backgroundColor: Colors.blue,
      ),
    ));
  }

  Widget cameraControl(context) {
    return Expanded(
      child: Align(
        alignment: Alignment.center,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          mainAxisSize: MainAxisSize.max,
          children: [
            FloatingActionButton(
              heroTag: null,
              onPressed: () {
                onCapture(context);
              },
              child: const Icon(Icons.camera),
              backgroundColor: Colors.redAccent,
            )
          ],
        ),
      ),
    );
  }

  getCameraLensIcon(lensDirection) {
    switch (lensDirection) {
      case CameraLensDirection.back:
        return CupertinoIcons.switch_camera;
      case CameraLensDirection.front:
        return CupertinoIcons.switch_camera_solid;
      case CameraLensDirection.external:
        return CupertinoIcons.photo_camera;
      default:
        return Icons.device_unknown;
    }
  }

  onSwitchCamera() {
    selectedCameraIndex = selectedCameraIndex! < cameras!.length - 1
        ? selectedCameraIndex! + 1
        : 0;
    CameraDescription selectedCamera = cameras![selectedCameraIndex!];
    initCamera(selectedCamera);
  }

  onCapture(context) async {
    try {
      await cameraController!.takePicture().then((value) {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (_) => PreviewScreen(
                      imgPath: value,
                    )));
      });
    } catch (e) {
      debugPrint('error $e');
    }
  }
}

 

Membuat Preview View

Kita buat dulu sebuah file preview dan masukkan kode seperti berikut.

import 'dart:convert';
import 'dart:io';
import 'package:appcamera/camera.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:http/http.dart' as http;

class PreviewScreen extends StatefulWidget {
  const PreviewScreen({Key? key, required this.imgPath}) : super(key: key);
  final XFile imgPath;

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

class _PreviewScreenState extends State<PreviewScreen> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
          children: [
            Expanded(
              flex: 2,
              child: Image.file(File(widget.imgPath.path), fit: BoxFit.cover),
            ),
          ],
        ),
        floatingActionButton: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            ElevatedButton.icon(
                style: ElevatedButton.styleFrom(primary: Colors.green),
                onPressed: () => Navigator.push(context,
                    MaterialPageRoute(builder: (_) => const CameraPage())),
                icon: const Icon(Icons.rotate_left),
                label: const Text("PHOTO ULANG")),
            ElevatedButton.icon(
                style: ElevatedButton.styleFrom(primary: Colors.red),
                onPressed: () {
                  //kirim absensi
                  uploadPhoto();
                },
                icon: const Icon(Icons.send_rounded),
                label: const Text("KIRIM SEKARANG")),
          ],
        ));
  }
}

 

Upload Photo Ke Database

Kita buat sebuah function yang berfungsi untuk handle upload photo yang telah kita ambil dan preview ke halaman preview.

uploadPhoto() async {
    var request = http.MultipartRequest(
        'POST', Uri.parse('http://api.sobatcoding.com/upload.php'));

    request.files.add(http.MultipartFile(
        'file',
        File(widget.imgPath.path).readAsBytes().asStream(),
        File(widget.imgPath.path).lengthSync(),
        filename: widget.imgPath.path.split("/").last));
    var res = await request.send();

    var responseBytes = await res.stream.toBytes();
    var responseString = utf8.decode(responseBytes);

    debugPrint("response: " + responseString.toString());
  }

 

Mengatasi Preview Camera Stretching dan Hasil Camera Depan Mirror

Untuk mengatasi camera streching atau cemet kita gunakan kode seperti berikut.

final size = MediaQuery.of(context).size;
    var scale = size.aspectRatio * cameraController!.value.aspectRatio;
    if (scale < 1) scale = 1 / scale;
    final double mirror = selectedCameraIndex == 1 ? math.pi : 0;

    return Transform(
      alignment: Alignment.center,
      transform: Matrix4.rotationY(mirror),
      child: Transform.scale(
        scale: scale,
        child: Center(
          child: CameraPreview(cameraController!),
        ),
      ),
    );

untuk mengatasi hasil camera depan mirror kita gunakan kode seperti berikut

//pengecekan penggunaan kamera depan atau belakang
final double mirror = selectedCameraIndex == 1 ? math.pi : 0;

return Transform(
      ...
      transform: Matrix4.rotationY(mirror),
     ...
    );

 

Flutter Camera Full Screen sobatcoding.com

Gambar flutter camera

 

Selamat mencoba.

Sekian tutorial kali ini, jika teman-teman memiliki pertanyaan atau saran mengenai artikel ini, jangan ragu untuk meninggalkan komentar pada form di bawah ini.

Semoga bermanfaat.