Mở file pubspec.yaml và cài đặt vào các thư viện trên:
image_picker: ^0.6.7+4 cached_network_image: ^2.2.0+1 image_editor: ^0.7.1 extended_image:git:url: git://github.com/codenameakshay/extended_image.git photo_view: ^0.9.2 gallery_saver: ^2.0.1
Tiếp đó đưa các tệp hoặc sao chép các mã code vào dự án và chỉnh sửa lại để phù hợp và có thể chạy với project. Kết quả thu được như sau:
Hình 4.30 Image_enhance
Về các chức năng, tai màn hình image_enhance, chúng ta có thể chọn một hình ảnh để bắt đầu chỉnh sửa, thư viện image_picker của flutter hỗ trợ cho chúng ta dễ dàng chọn và lưu ảnh trong một biến, sau đó chúng ta sẽ chuyển ảnh đó qua màn hình edit_screen để bắt đầu chỉnh sửa:
- Khai báo các thư viện:
import 'package:image_picker/image_picker.dart'; import 'package:extended_image/extended_image.dart'; import 'save_screen.dart';
import 'package:image_editor/image_editor.dart' hide ImageSource; import 'package:gallery_saver/gallery_saver.dart';
import 'package:photo_view/photo_view.dart'; - Chọn ảnh:
final pickedFile = await picker.getImage(source: ImageSource.gallery); - Chỉnh sửa ảnh:
Navigator.push( context,
CupertinoPageRoute(
builder: (context) => EditPhotoScreen( arguments: [_image],
), ),
),
Ở màn hình edit, ta sẽ thực hiện chỉnh sửa hình ảnh, thư viện image_editor hầu như đã hỗ trợ gần hết mọi thứ để chúng ta có thể chỉnh sửa ảnh cơ bản một cách đơn giản, mọi công việc chỉ cần gọi hàm và thực hiện:
- Xoay ảnh: Ta truyền vào hàm giá trị true hoặc false, nếu true, sẽ lật về bên phải (tức là 90o về bên phải) và nếu là false sẽ lật về bên trái (tức là 90o về bên trái), hoặc chúng ta có thể điều chỉnh code thay vì rotate(right) thành rotate(left) để có thể đổi hướng lật.
void rotate(bool right) { editorKey.currentState.rotate(right: right); } - Lật ảnh: void flip() { editorKey.currentState.flip(); }
Khi gọi hàm, ảnh sẽ đơn giản được lật ngược lại so với chiều ban đầu theo chiều ngang.
- Cắt ảnh: Thư viện extended_image của flutter cũng hỗ trợ đầy đủ cho các chức năng cắt ảnh:
o Lấy dữ liệu hình ảnh thô và trực tiếp được cắt từ ExtendedImageEditorState():
final Rect rect = state.getCropRect(); final Uint8List img = state.rawImageData;
o Chuẩn bị các cài đặt cắt ảnh:
final EditActionDetails action = state.editAction; final double radian = action.rotateAngle;
final bool flipHorizontal = action.flipY; final bool flipVertical = action.flipX; final Uint8List img = state.rawImageData;
final ImageEditorOption option = ImageEditorOption();
option.addOption(ClipOption.fromRect(rect));
option.addOption(FlipOption(horizontal: flipHorizontal, vertical: flipVertical));
if (action.hasRotateAngle) { option.addOption(RotateOption(radian.toInt())); } option.addOption(ColorOption.saturation(sat)); option.addOption(ColorOption.brightness(bright + 1)); option.addOption(ColorOption.contrast(con));
option.outputFormat = const OutputFormat.jpeg(100); o Cắt ảnh với editImage:
final Uint8List result = await ImageEditor.editImage(
image: img,imageEditorOption: option, );
Ảnh sau khi được chỉnh sửa sẻ ở dạng Image data và có thể sử dụng để lưu ảnh hoặc thực hiện bất cứ tác vụ nào khác cho chỉnh sửa ảnh.
- Đổi độ sang, độ tương phản, độ bão hòa:
Thư viện image_editor của flutter sử dụng ma trận 5x4 để chuyển đổi màu sắc và các thành phần của một bitmap ảnh. Ma trận có thể được truyền dưới mảng đơn:
o Khai báo màu mặc định: final defaultColorMatrix = const <double>[
1, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0
];
o Hàm dùng để tính toán màu bão hòa
List<double> calculateSaturationMatrix(double saturation) { final m = List<double>.from(defaultColorMatrix);
final R = 0.213 * invSat; final G = 0.715 * invSat; final B = 0.072 * invSat; m[0] = R + saturation; m[1] = G; m[2] = B; m[5] = R; m[6] = G + saturation; m[7] = B; m[10] = R; m[11] = G; m[12] = B + saturation; return m; }
o Tính tốn đợ tương phản:
List<double> calculateContrastMatrix(double contrast) { final m = List<double>.from(defaultColorMatrix); m[0] = contrast; m[6] = contrast; m[12] = contrast; return m; }
Ảnh sau khi được chỉnh sửa sẽ được chuyên sang màn hình dưới dạng file, từ đó ta có thể lưu trữ ảnh vào hệ thống hoặc chia sẻ.
Trước tiên để lưu hình ảnh, ta cần phải đổi tên hình ảnh đó để tránh bị trùng lặp
void renameImage() {
String ogPath = image.path;
List<String> ogPathList = ogPath.split('/');
String ogExt = ogPathList[ogPathList.length - 1].split('.')[1]; DateTime today = new DateTime.now();
String dateSlug = "${today.day.toString().padLeft(2, '0')}-${today.month.toString().padLeft(2, '0')}-${today.year.toString()}_${today.hour.toString().padLeft(2, '0')}-$ {today.minute.toString().padLeft(2, '0')}-${today.second.toString().padLeft(2, '0')}"; image = image.renameSync( "${ogPath.split('/image')[0]}/PhotoEditor_$dateSlug.$ogExt"); print(image.path); }
Sau đó sử dụng thư viên gallery_image để lưu hình ảnh vào thư viện:
Future saveImage() async { renameImage();
await GallerySaver.saveImage(image.path, albumName: "PhotoEditor"); setState(() {savedImage = true;});
}
Ảnh sẽ được lưu vào thư viện hình ảnh và được lưu trong album forlder PhotoEditor. Có thể đổi đích lưu trữ bằng cách đổi tên PhotoEditor bằng tên mong muốn.