[flutter] 플러터 Riverpod를 사용하여 앱에 사진 필터 기능을 추가하는 방법은 어떻게 되나요?

이 문서에서는 Flutter에서 Riverpod를 사용하여 앱에 사진 필터 기능을 추가하는 방법을 안내합니다. Riverpod는 Flutter의 의존성 주입(Dependency Injection)과 상태 관리(State Management)를 도와주는 라이브러리입니다.

1. 프로젝트 설정

먼저, Flutter 프로젝트를 생성하고 Riverpod를 추가해야 합니다. 이를 위해서 프로젝트의 pubspec.yaml 파일에 다음과 같은 의존성을 추가합니다:

dependencies:
  flutter:
    sdk: flutter
  riverpod: ^1.0.4

의존성을 추가한 후, pubspec.yaml 파일이 있는 디렉토리에서 터미널을 열고 다음 명령을 실행하여 의존성을 다운로드합니다:

flutter pub get

2. 필터 기능 구현

사진 필터 기능을 구현하기 위해서는 먼저 필터링을 할 수 있는 이미지 처리 라이브러리를 선택해야 합니다. Flutter에서는 image 패키지가 널리 사용되지만, 해당 라이브러리와 함께 image_filters 패키지도 설치해야 합니다. 따라서 pubspec.yaml 파일에 다음과 같은 의존성을 추가합니다:

dependencies:
  image: ^3.0.2
  image_filters: ^1.0.1

의존성을 추가한 후, pubspec.yaml 파일이 있는 디렉토리에서 터미널을 열고 다음 명령을 실행하여 의존성을 다운로드합니다:

flutter pub get

이제 필터링 기능을 구현할 수 있습니다. 필터링할 이미지를 선택하고 해당 이미지에 필터를 적용하려면 다음과 같은 코드를 작성합니다:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;
import 'package:image_filters/image_filters.dart';

// 이미지 필터링
img.Image applyFilter(File image, ImageFilterType filterType) {
  img.Image originalImage = img.decodeImage(image.readAsBytesSync())!;
  img.Image filteredImage = img.copyResize(originalImage, width: 300);
  return img.applyFilter(filteredImage, filterType);
}

// 필터링된 이미지를 화면에 나타내는 위젯
class FilteredImage extends StatelessWidget {
  final File image;
  final ImageFilterType filterType;

  FilteredImage(this.image, this.filterType);

  @override
  Widget build(BuildContext context) {
    img.Image filteredImage = applyFilter(image, filterType);
    return Image.memory(
      img.encodePng(filteredImage),
      fit: BoxFit.cover,
    );
  }
}

// 필터링된 이미지를 보여주는 페이지
class FilteredImagePage extends StatelessWidget {
  final File image;
  final ImageFilterType filterType;

  FilteredImagePage(this.image, this.filterType);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Filtered Image'),
      ),
      body: Center(
        child: FilteredImage(image, filterType),
      ),
    );
  }
}

위 코드에서 applyFilter 함수는 선택한 이미지와 필터 타입을 인자로 받아 해당 이미지에 필터를 적용한 후 반환합니다. 그리고 FilteredImage 위젯은 필터링된 이미지를 화면에 나타내기 위해 사용되며, FilteredImagePage 위젯은 필터링된 이미지를 보여주는 페이지를 구성합니다.

3. Riverpod를 이용한 상태 관리

이제 Riverpod를 사용하여 필터링 기능을 상태 관리하도록 구성해보겠습니다. 먼저, filterType을 저장할 상태 공급자(State Provider)를 정의합니다:

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:image_filters/image_filters.dart';

final filterTypeProvider = StateProvider<ImageFilterType>((ref) {
  return ImageFilterType.none;
});

그다음, FilteredImagePage 위젯을 다음과 같이 수정합니다:

class FilteredImagePage extends ConsumerWidget {
  final File image;

  FilteredImagePage(this.image);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final filterType = watch(filterTypeProvider).state;
    return Scaffold(
      appBar: AppBar(
        title: Text('Filtered Image'),
      ),
      body: Center(
        child: FilteredImage(image, filterType),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          context.read(filterTypeProvider).state = ImageFilterType.grayscale;
        },
        child: Icon(Icons.filter),
      ),
    );
  }
}

위 코드에서 FilteredImagePage 위젯은 ConsumerWidget을 상속받도록 수정되었으며, filterType 상태는 filterTypeProvider의 상태를 읽어오도록 변경되었습니다. 그리고 필터 타입을 변경하기 위한 FloatingActionButton을 추가하여 필터링을 트리거할 수 있도록 합니다.

4. 앱에서 필터링 기능 사용하기

이제 필터링 기능을 앱의 다른 부분에서 사용할 수 있습니다. 예를 들어, 이미지 목록을 보여주는 페이지에서 각 이미지에 필터링된 썸네일을 표시하고 싶다면 다음과 같이 코드를 수정할 수 있습니다:

class ImageListPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final filterType = watch(filterTypeProvider).state;
    final List<File> images = getImageList(); // 이미지 목록 가져오기

    return ListView.builder(
      itemCount: images.length,
      itemBuilder: (context, index) {
        return ListTile(
          leading: FilteredImage(images[index], filterType),
          title: Text('Image ${index + 1}'),
        );
      },
    );
  }
}

위 코드에서 FilteredImage 위젯을 ListTile 위젯의 leading 속성에 추가하여 필터링된 이미지의 썸네일을 표시합니다.

결론

이제 Riverpod를 사용하여 Flutter 앱에 사진 필터 기능을 추가하는 방법을 배웠습니다. Riverpod를 이용하면 의존성 주입과 상태 관리를 효과적으로 구현할 수 있으며, 필터링 기능을 다른 부분에서도 활용할 수 있습니다. 이를 통해 더욱 다양하고 유연한 앱을 개발할 수 있습니다.