Tested on: Chrome(Version 80.0.3987.163 (Official Build) (64-bit)), Mozilla Firefox(75.0 (64-bit))
deps:
crop: ^0.3.1+1
image_picker_web: ^1.0.6
image_picker: ^0.6.5
import 'package:flutter/material.dart';
import 'package:image_picker_web/image_picker_web.dart';
import './image.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:ui';
import './centered_slider_track_shape.dart';
import 'package:flutter/material.dart';
import 'package:crop/crop.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path/path.dart' as Path;
import 'package:path_provider/path_provider.dart';
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'dart:math';
class UserPage extends StatefulWidget {
@override
_UserPageState createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
Image pickedImage;
@override
void initState() {
super.initState();
}
Future getImageMobile() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
pickedImage = Image.file(
image,
fit: BoxFit.cover,
);
});
}
getImageWeb() async {
Image fromPicker =
await ImagePickerWeb.getImage(outputType: ImageType.widget);
if (fromPicker != null) {
setState(() {
pickedImage = fromPicker;
});
}
}
pickImage() async {
if (kIsWeb) {
await getImageWeb();
} else {
await getImageMobile();
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Image Picker Web Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 300),
switchInCurve: Curves.easeIn,
child: SizedBox(
width: 200,
child: pickedImage,
) ??
Container(),
),
SizedBox(
width: 15,
),
],
),
ButtonBar(alignment: MainAxisAlignment.center, children: <Widget>[
RaisedButton(
onPressed: () => pickImage(),
child: Text('Select Image'),
),
RaisedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (_) => ImagePage(
image: pickedImage,
)),
);
},
child: Text('Crop'),
),
]),
])),
),
);
}
}
class ImagePage extends StatefulWidget {
ImagePage({Key key, @required this.image}) : super(key: key);
final Image image;
@override
_ImagePageState createState() => _ImagePageState(image);
}
class _ImagePageState extends State<ImagePage> {
_ImagePageState(this.image);
final Image image;
String _uploadedFileURL;
final controller = CropController(aspectRatio: 1000 / 667.0);
double _rotation = 0;
@override
void initState(){
super.initState();
controller.aspectRatio = 1;
setState(() {
});
}
void _cropImage() async {
final pixelRatio = MediaQuery.of(context).devicePixelRatio;
final cropped = await controller.crop(pixelRatio: pixelRatio);
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(
title: Text('Crop Result'),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.file_upload),
tooltip: 'Upload',
onPressed: () async {
// getting a directory path for saving
var dir = await getApplicationDocumentsDirectory();
final ByteData data = await cropped.toByteData(format: ImageByteFormat.png);
final buffer = data.buffer;
final String fileName = Random().nextInt(10000).toString() +'.png';
print(fileName);
final File newImage = await new File('${dir.path}/$fileName').writeAsBytes(
buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
await uploadFile(newImage);
},
),
],
),
body: Center(
child: RawImage(
image: cropped,
),
),
),
fullscreenDialog: true,
),
);
}
Future uploadFile(File img) async {
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Crop Demo'),
centerTitle: true,
actions: <Widget>[
IconButton(
onPressed: _cropImage,
tooltip: 'Crop',
icon: Icon(Icons.crop),
)
],
),
body: Column(
children: <Widget>[
Expanded(
child: Container(
color: Colors.black,
padding: EdgeInsets.all(8),
child: Crop(
controller: controller,
child: image,
helper: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 2),
),
),
),
),
),
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.undo),
tooltip: 'Undo',
onPressed: () {
controller.rotation = 0;
controller.scale = 1;
controller.offset = Offset.zero;
setState(() {
_rotation = 0;
});
},
),
Expanded(
child: SliderTheme(
data: theme.sliderTheme.copyWith(
trackShape: CenteredRectangularSliderTrackShape(),
),
child: Slider(
divisions: 361,
value: _rotation,
min: -180,
max: 180,
label: '$_rotation°',
onChanged: (n) {
setState(() {
_rotation = n.roundToDouble();
controller.rotation = _rotation;
});
},
),
),
),
],
),
],
),
);
}
}