이 문서에서는 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를 이용하면 의존성 주입과 상태 관리를 효과적으로 구현할 수 있으며, 필터링 기능을 다른 부분에서도 활용할 수 있습니다. 이를 통해 더욱 다양하고 유연한 앱을 개발할 수 있습니다.