feat: ImagePickerConfig for setting image size and quality

This commit is contained in:
Stein Milder 2022-11-07 14:03:20 +01:00
parent 324b2b791f
commit 44b0c92ea6
4 changed files with 141 additions and 113 deletions

View file

@ -1,4 +1,5 @@
library flutter_image_picker; library flutter_image_picker;
export 'src/models/image_picker_theme.dart'; export 'src/models/image_picker_theme.dart';
export 'src/models/image_picker_config.dart';
export 'src/ui/image_picker.dart'; export 'src/ui/image_picker.dart';

View file

@ -0,0 +1,20 @@
class ImagePickerConfig {
/// The [ImagePickerConfig] is used to configure the [ImagePicker].
const ImagePickerConfig({
this.maxWidth,
this.maxHeight,
this.imageQuality,
});
/// If specified, the image will be at most `maxWidth` wide and
/// `maxHeight` tall. Otherwise the image will be returned at it's
/// original width and height.
/// The `imageQuality` argument modifies the quality of the image, ranging from 0-100
/// where 100 is the original/max quality. If `imageQuality` is null, the image with
/// the original quality will be returned. Compression is only supported for certain
/// image types such as JPEG and on Android PNG and WebP, too. If compression is not supported for the image that is picked,
/// a warning message will be logged.
final double? maxWidth;
final double? maxHeight;
final int? imageQuality;
}

View file

@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter_image_picker/src/models/image_picker_config.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
/// The Image Picker Service class is the functionality of the Image Picker package which uses the Image Picker package to choose an image. /// The Image Picker Service class is the functionality of the Image Picker package which uses the Image Picker package to choose an image.
@ -12,10 +13,15 @@ class ImagePickerService {
/// [pickImage] is the function that picks the image and returns it as a [Uint8List]. /// [pickImage] is the function that picks the image and returns it as a [Uint8List].
/// The function requires [source], an [ImageSource] that's the method of how the image needs to be picked, for example gallery or camera. /// The function requires [source], an [ImageSource] that's the method of how the image needs to be picked, for example gallery or camera.
Future<Uint8List?> pickImage(ImageSource source) async { Future<Uint8List?> pickImage(
var image = ImageSource source, {
await (await (imagePicker ?? ImagePicker()).pickImage(source: source)) ImagePickerConfig? config,
?.readAsBytes(); }) async =>
return image; await (await (imagePicker ?? ImagePicker()).pickImage(
} source: source,
maxWidth: config?.maxWidth,
maxHeight: config?.maxHeight,
imageQuality: config?.imageQuality,
))
?.readAsBytes();
} }

View file

@ -1,24 +1,28 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_image_picker/flutter_image_picker.dart';
import 'package:flutter_image_picker/src/services/image_picker_service.dart'; import 'package:flutter_image_picker/src/services/image_picker_service.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import '../models/image_picker_theme.dart'; /// The Image Picker class generates the Image Picker Widget which can be displayed in your application. If you call the class you can give it 4 optional variables:
/// The Image Picker class generates the Image Picker Widget which can be displayed in your application. If you call the class you can give it 3 optional variables:
/// The first one is the [ImagePickerTheme] which can be used to change the UI of the widget. /// The first one is the [ImagePickerTheme] which can be used to change the UI of the widget.
/// The second one is your own implementation of the ImagePickerService. Which can be used in testing for example. /// The second one is the [ImagePickerConfig] which can be used to configure the behaviour of the image picker.
/// The third one is a custom Button widget. /// The third one is your own implementation of the ImagePickerService. Which can be used in testing for example.
/// The fourth one is a custom Button widget.
class ImagePicker extends StatelessWidget { class ImagePicker extends StatelessWidget {
const ImagePicker( const ImagePicker({
{Key? key, Key? key,
this.imagePickerTheme = const ImagePickerTheme(), this.imagePickerTheme = const ImagePickerTheme(),
this.imagePickerService, this.imagePickerConfig = const ImagePickerConfig(),
this.customButton}) this.imagePickerService,
: super(key: key); this.customButton,
}) : super(key: key);
/// ImagePickerTheme can be used to change the UI of the Image Picker Widget to change the text/icons to your liking. /// ImagePickerTheme can be used to change the UI of the Image Picker Widget to change the text/icons to your liking.
final ImagePickerTheme imagePickerTheme; final ImagePickerTheme imagePickerTheme;
/// ImagePickerConfig can be used to define the size and quality for the uploaded image.
final ImagePickerConfig imagePickerConfig;
/// The Image Picker Dialog can have a custom button if you want to. /// The Image Picker Dialog can have a custom button if you want to.
final StatelessWidget? customButton; final StatelessWidget? customButton;
@ -26,77 +30,76 @@ class ImagePicker extends StatelessWidget {
final ImagePickerService? imagePickerService; final ImagePickerService? imagePickerService;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => SingleChildScrollView(
return SingleChildScrollView(
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
ListTile( ListTile(
tileColor: imagePickerTheme.titleBackgroundColor, tileColor: imagePickerTheme.titleBackgroundColor,
title: Text( title: Text(
textAlign: imagePickerTheme.titleAlignment, textAlign: imagePickerTheme.titleAlignment,
imagePickerTheme.title, imagePickerTheme.title,
style: TextStyle( style: TextStyle(
fontFamily: imagePickerTheme.font, fontFamily: imagePickerTheme.font,
fontSize: imagePickerTheme.titleTextSize, fontSize: imagePickerTheme.titleTextSize,
color: imagePickerTheme.titleColor, color: imagePickerTheme.titleColor,
),
),
), ),
), const SizedBox(height: 20),
), Row(
const SizedBox( mainAxisAlignment: MainAxisAlignment.center,
height: 20, children: [
), _generateIconButtonWithText(
Row( context,
mainAxisAlignment: MainAxisAlignment.center, imagePickerTheme.selectImageIcon,
children: [ imagePickerTheme,
_generateIconButtonWithText( Icons.image,
context, ImageSource.gallery,
imagePickerTheme.selectImageIcon, imagePickerTheme.selectImageText,
imagePickerTheme, ),
Icons.image, SizedBox(
ImageSource.gallery, width: imagePickerTheme.spaceBetweenIcons,
imagePickerTheme.selectImageText), ),
SizedBox( _generateIconButtonWithText(
width: imagePickerTheme.spaceBetweenIcons, context,
imagePickerTheme.makePhotoIcon,
imagePickerTheme,
Icons.camera_alt_rounded,
ImageSource.camera,
imagePickerTheme.makePhotoText,
),
],
), ),
_generateIconButtonWithText( const SizedBox(height: 10),
context, Row(
imagePickerTheme.makePhotoIcon, mainAxisAlignment: MainAxisAlignment.center,
imagePickerTheme, children: [
Icons.camera_alt_rounded, SizedBox(
ImageSource.camera, width: imagePickerTheme.closeButtonWidth,
imagePickerTheme.makePhotoText), height: imagePickerTheme.closeButtonHeight,
], child: customButton ??
), ElevatedButton(
const SizedBox( style: ElevatedButton.styleFrom(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: imagePickerTheme.closeButtonWidth,
height: imagePickerTheme.closeButtonHeight,
child: customButton ??
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor:
imagePickerTheme.closeButtonBackgroundColor), imagePickerTheme.closeButtonBackgroundColor,
onPressed: () => Navigator.of(context).pop(), ),
child: Text(imagePickerTheme.closeButtonText, onPressed: () => Navigator.of(context).pop(),
child: Text(
imagePickerTheme.closeButtonText,
style: TextStyle( style: TextStyle(
fontFamily: imagePickerTheme.font, fontFamily: imagePickerTheme.font,
fontSize: imagePickerTheme.closeButtonTextSize, fontSize: imagePickerTheme.closeButtonTextSize,
color: imagePickerTheme.closeButtonTextColor, color: imagePickerTheme.closeButtonTextColor,
))), ),
) ),
),
)
],
),
const SizedBox(height: 30),
], ],
), ),
const SizedBox( );
height: (30),
),
],
));
}
/// The [_generateIconButtonWithText] function returns a column that includes an [IconButton] and [Text]. /// The [_generateIconButtonWithText] function returns a column that includes an [IconButton] and [Text].
/// The function requires the following parameters to be able to generate an icon with text: /// The function requires the following parameters to be able to generate an icon with text:
@ -106,41 +109,39 @@ class ImagePicker extends StatelessWidget {
/// [imageSource] The type of [ImageSource] to be used to pick an image when pressed on the icon. /// [imageSource] The type of [ImageSource] to be used to pick an image when pressed on the icon.
/// [bottomText] The text that's displayed underneath the icon. /// [bottomText] The text that's displayed underneath the icon.
Column _generateIconButtonWithText( Column _generateIconButtonWithText(
BuildContext context, BuildContext context,
Widget? customIcon, Widget? customIcon,
ImagePickerTheme imagePickerTheme, ImagePickerTheme imagePickerTheme,
IconData icon, IconData icon,
ImageSource imageSource, ImageSource imageSource,
String bottomText) { String bottomText) =>
return Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
InkWell( InkWell(
key: Key(bottomText), key: Key(bottomText),
onTap: () async { onTap: () async {
final navigator = Navigator.of(context); final navigator = Navigator.of(context);
var image = await (imagePickerService ?? ImagePickerService()) var image = await (imagePickerService ?? ImagePickerService())
.pickImage(imageSource); .pickImage(imageSource, config: imagePickerConfig);
navigator.pop(image); navigator.pop(image);
}, },
child: customIcon ?? child: customIcon ??
Icon( Icon(
icon, icon,
size: imagePickerTheme.iconSize, size: imagePickerTheme.iconSize,
color: imagePickerTheme.iconColor, color: imagePickerTheme.iconColor,
), ),
), ),
Text( Text(
bottomText, bottomText,
style: TextStyle( style: TextStyle(
fontFamily: imagePickerTheme.font, fontFamily: imagePickerTheme.font,
fontSize: imagePickerTheme.iconTextSize, fontSize: imagePickerTheme.iconTextSize,
color: imagePickerTheme.textColor), color: imagePickerTheme.textColor,
), ),
const SizedBox( ),
height: 20, const SizedBox(height: 20),
), ],
], );
);
}
} }