Is there any api for Image editor in flutter app. I need adding texts in image - image

Is it possible to edit image like to rotate and to add text over image. Is there any plugin for that? I need an editor for image to add texts with various fonts and colors. Thank you

you should use RepaintBoundary to capture it as a widget and to overlap widget use stack.
Look at this code how to capture widget as a image.
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
GlobalKey _globalKey = new GlobalKey();
bool inside = false;
Uint8List imageInMemory;
Future<Uint8List> _capturePng() async {
try {
print('inside');
inside = true;
RenderRepaintBoundary boundary =
_globalKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
ByteData byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
// String bs64 = base64Encode(pngBytes);
// print(pngBytes);
// print(bs64);
print('png done');
setState(() {
imageInMemory = pngBytes;
inside = false;
});
return pngBytes;
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
return RepaintBoundary(
key: _globalKey,
child: new Scaffold(
appBar: new AppBar(
title: new Text('Widget To Image demo'),
),
body: SingleChildScrollView(
child: Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
'click the button below to capture image',
),
new RaisedButton(
child: Text('capture Image'),
onPressed: _capturePng,
),
inside ? CircularProgressIndicator()
:
imageInMemory != null
? Container(
child: Image.memory(imageInMemory),
margin: EdgeInsets.all(10))
: Container(),
],
),
),
)),
);
}
}

Related

How to embed watermark (Text or Image) in Flutter

I created an app with image picker and I want to embed a text or image to that selected picture and saved it to gallery.
👇 My App
👇 I tried to create this
This is the code I used for image picker
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Watermark',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
File _pickedImage;
Future pickAnImage() async {
final pickedFile =
await ImagePicker().getImage(source: ImageSource.gallery);
setState(() {
_pickedImage = File(pickedFile.path);
});
}
_saveImage() {
//TODO: Save image to gallery
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text("Flutter Watermark"),
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: <Widget>[
_pickedImage == null
? TextButton(
child: Text("Pick an Image"),
onPressed: pickAnImage,
)
: Column(
children: [
Image.file(_pickedImage),
SizedBox(
height: 50.0,
),
TextButton(
onPressed: _saveImage, child: Text("Save Image"))
],
),
],
),
),
),
),
);
}
}
I followed the below tutorial but it is freeze the app and I couldn't implement it.
Tutorial
https://medium.com/flutter-community/add-watermark-over-image-in-flutter-e7353e3cf603
Can anyone help me please?
You can try using this dependency:
As suggested by the author, this example is similar to your query
import 'dart:io';
import 'package:image/image.dart';
void main() {
// Create an image
Image image = Image(320, 240);
// Draw some text using 24pt arial font
drawString(image, arial_24, 0, 0, 'Hello World');
// Save the image to disk as a PNG
File('test.png').writeAsBytesSync(encodePng(image));
}
Image downloaded from this link.

How to Display Picked Image in Flutter

I want to Pick a image and then display the picked Image. So I tried doing this->
class ImageUploadChoice extends StatefulWidget {
#override
_ImageUploadChoiceState createState() => _ImageUploadChoiceState();
}
class _ImageUploadChoiceState extends State<ImageUploadChoice> {
File imageFile;
Future getImage(int type) async {
PickedFile pickedImage = await ImagePicker().getImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
imageQuality: 50
);
return pickedImage;
}
For Displaying Image
Expanded(
child: Container(
child: imageFile != null
? Image.file(
imageFile,
height: MediaQuery.of(context).size.height / 5,
)
: Text("Pick up the image"),
),
),
For Calling Function->
new ListTile(
leading: new Icon(
Icons.photo_library,
color: Colors.black,),
title: new Text(
'Photo Library',
style: getTextStyle(MediaQuery.of(context).size.height, "heading2"),
),
onTap: () async {
final tmpFile = await getImage(2);
setState(() {
imageFile = tmpFile;
});
Navigator.pop(context);
Navigator.of(context).pop();
}),
But It's not Working. The Selected Image is not been displayed. What else I need to do?
Made a sample code and it's working fine. Remove following lines
Navigator.pop(context);
Navigator.of(context).pop();
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Test(),
);
}
}
class Test extends StatefulWidget {
#override
_Test createState() => _Test();
}
class _Test extends State<Test> {
File imageFile;
Future getImage() async {
final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
imageFile = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: InkWell(
onTap: (){
getImage();
},
child: Icon(
Icons.add
),
),
body: Center(
child: root(),
),
);
}
Widget root() {
return Container(
child: imageFile != null
? Image.file(
imageFile,
height: MediaQuery
.of(context)
.size
.height / 5,
)
: Text("Pick up the image"),
);
}
}

converting image to base64 in flutter

I take a picture with phone's camera, then resize it and convert it to base64 string. However, after those manipulations, base64 string that I get doesn't seem to be valid.
I try to convert it back to image on this website https://codebeautify.org/base64-to-image-converter . After I click generate image, nothing happens, however sample on their website works. Tried on the other websites and still no luck.
My code:
import 'package:image/image.dart' as img;
import 'package:image_picker/image_picker.dart';
File _photo;
String photoBase64;
Future getImage(ImageSource source) async {
var photo = await ImagePicker.pickImage(source: source);
img.Image image = img.decodeImage(photo.readAsBytesSync());
img.Image imageResized = img.copyResize(image, width: 120);
setState(() {
_photo = photo;
List<int> imageBytes = imageResized.getBytes();
photoBase64 = base64Encode(imageBytes);
});
}
I tried base64UrlEncode() too, however the issue still remains. String I am trying to convert back to image is photoBase64. My goal is to send it in a body of a POST request later. What exactly am I doing wrong here?
Thank you
You can copy paste run full code below
You can use package https://pub.dev/packages/flutter_native_image to get resized image
imageResized = await FlutterNativeImage.compressImage(photo.path,
quality: 100, targetWidth: 120, targetHeight: 120);
...
List<int> imageBytes = imageResized.readAsBytesSync();
working demo
full code
import 'package:flutter/material.dart';
import 'package:image/image.dart' as img;
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'dart:convert';
import 'package:flutter_native_image/flutter_native_image.dart';
void main() => runApp(MyApp());
File _photo;
String photoBase64;
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
File imageResized;
Future getImage(ImageSource source) async {
var photo = await ImagePicker.pickImage(source: source);
imageResized = await FlutterNativeImage.compressImage(photo.path,
quality: 100, targetWidth: 120, targetHeight: 120);
setState(() {
_photo = photo;
List<int> imageBytes = imageResized.readAsBytesSync();
photoBase64 = base64Encode(imageBytes);
print(photoBase64);
});
}
void _incrementCounter() {
getImage(ImageSource.camera);
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
imageResized == null ? Container() : Image.file(imageResized),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
my solution
Future getImage() async {
pickedFile =
await _picker.getImage(source: ImageSource.gallery, imageQuality: 50);
setState(() {
if (pickedFile != null) {
file = File(pickedFile!.path);
final bytes =
file!.readAsBytesSync();
img64 = base64Encode(bytes);
} else {
print('No image selected.');
}
});
}

Is there a way I can read thumbnails from phone gallery?

I am trying to display all the phone gallery images myself by reading the external files directory and possibly every image that ends with jpg or png. I achieved that, but could not display all of them in a grid as due to their sizes or the no. of images, the app crashes. Code looks bit like this..
new GridView.count(
shrinkWrap: true,
physics: new ClampingScrollPhysics(),
crossAxisCount: 2,
// children: new List<Widget>.generate(_images.length, (index) {
// children: new List<Widget>.generate(allImages.length, (index) {
children: new List<Widget>.generate(_PhoneImages.length, (index) {
File imgFile = _phoneImageFiles[index];
thumbBytes = _phoneThumbBytes[index]; // assuming it got created!!!
// print('thumbbytes $thumbBytes');
print('phone image index: $index');
return new GridTile(
child: new GestureDetector(
child: new Stack(
children: [
new Card(
// color: Colors.blue.shade200,
color: Colors.white70,
child: new Center(
// child: new Text('tile $index'),
// child: new Image.asset(_images[index]),
/*
child: new CachedNetworkImage(
imageUrl: allImages[index].path,
// placeholder: new CircularProgressIndicator(),
errorWidget: new Icon(Icons.error),
)
*/
child: new Image.file(imgFile,
// child: new Image.memory(thumbBytes,
So I tried the imageresize library which tells me to do a heavy operation of resizing, that takes almost 20 minutes before I can show the thumbnails.
All I need is to read thumbnails from gallery like how the phone gallery displays. I don't need categorization. I need all and a link to their full version so that I can do something with them later on.
I think this might help multi_image_picker
e.g
import 'package:flutter/material.dart';
import 'package:multi_image_picker/asset.dart';
class AssetView extends StatefulWidget {
final int _index;
final Asset _asset;
AssetView(this._index, this._asset);
#override
State<StatefulWidget> createState() => AssetState(this._index, this._asset);
}
class AssetState extends State<AssetView> {
int _index = 0;
Asset _asset;
AssetState(this._index, this._asset);
#override
void initState() {
super.initState();
_loadImage();
}
void _loadImage() async {
await this._asset.requestThumbnail(300, 300); // here requesting thumbnail
setState(() {});
}
#override
Widget build(BuildContext context) {
if (null != this._asset.thumbData) {
return Image.memory(
this._asset.thumbData.buffer.asUint8List(),
fit: BoxFit.cover,
);
}
return Text(
'${this._index}',
style: Theme.of(context).textTheme.headline,
);
}
}
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:multi_image_picker/asset.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'asset_view.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Asset> images = List<Asset>();
String _error;
#override
void initState() {
super.initState();
}
Widget buildGridView() {
return GridView.count(
crossAxisCount: 3,
children: List.generate(images.length, (index) {
return AssetView(index, images[index]);
}),
);
}
Future<void> loadAssets() async {
setState(() {
images = List<Asset>();
});
List resultList;
String error;
try {
resultList = await MultiImagePicker.pickImages(
maxImages: 300,
);
} on PlatformException catch (e) {
error = e.message;
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
images = resultList;
if (error == null) _error = 'No Error Dectected';
});
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('Plugin example app'),
),
body: Column(
children: <Widget>[
Center(child: Text('Error: $_error')),
RaisedButton(
child: Text("Pick images"),
onPressed: loadAssets,
),
Expanded(
child: buildGridView(),
)
],
),
),
);
}
}

Hero Animation Not Working in Flutter

So, I'm trying to make a home delivery app for a restaurant in flutter and I can't seem to get my hero animation working. First I made a splash screen where the logo shows up and then it navigates to home page where the logo is supposed to do a hero transition. The splash screen and the home page are in two separate dart files. Here's the code for my splash screen:
import 'package:flutter/material.dart';
import 'home_page.dart';
import 'dart:async';
class Splash extends StatefulWidget {
#override
_SplashState createState() => new _SplashState();
}
class _SplashState extends State<Splash> with SingleTickerProviderStateMixin
{
Animation<double> _mainLogoAnimation;
AnimationController _mainLogoAnimationController;
#override
void initState() {
super.initState();
goToHomePage();
_mainLogoAnimationController = new AnimationController(duration: new Duration(milliseconds: 2500) ,vsync: this);
_mainLogoAnimation = new CurvedAnimation(parent:
_mainLogoAnimationController, curve: Curves.easeIn);
_mainLogoAnimation.addListener(() => (this.setState(() {})));
_mainLogoAnimationController.forward();
}
Future goToHomePage() async {
await new Future.delayed(const Duration(milliseconds: 4000));
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new HomePage()));
}
#override
Widget build(BuildContext context) {
return new Material(
color: Colors.black,
child: new Center(
child: new Opacity(
opacity: 1.0 * _mainLogoAnimation.value,
child: new Hero(
tag: 'tbh_logo',
child: new Image(
image: new AssetImage('assets/images/tbh_main_logo.png'),
width: 300.0
)
)
)
)
);
}
}
And here's the code for the home page:
import 'package:flutter/material.dart';
import '../ui/drawer.dart';
import 'splash.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("The Barni House"),
backgroundColor: Colors.black,
),
drawer: new Drawer(child: MyDrawer()),
body: new Center(
child: Column(
children: <Widget>[
new Container(
child: new Hero(
tag: 'tbh_logo',
child: new Image(
image: new AssetImage('assets/images/tbh_main_logo.png'),
width: 300.0
)
)
)
],
)
),
);
}
}
Checked your code so the hero animation is working but its happening to fast because of the transition duration is only 300 milliseconds.
To achieve the below result you can make a Custom MaterialPageRoute.
Before
#override
Duration get transitionDuration => const Duration(milliseconds: 300);
After
#override
Duration get transitionDuration => const Duration(milliseconds: 1000);
Also, you can play with the CurvedAnimation
new CurvedAnimation(
parent: routeAnimation,
curve: Curves.elasticIn,
)
CustomRoute.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
final Tween<Offset> _kBottomUpTween = new Tween<Offset>(
begin: const Offset(0.0, 1.0),
end: Offset.zero,
);
// Offset from offscreen to the right to fully on screen.
final Tween<Offset> _kRightMiddleTween = new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
);
// Offset from offscreen below to fully on screen.
class AppPageRoute extends MaterialPageRoute<String> {
#override
final bool maintainState;
#override
final WidgetBuilder builder;
CupertinoPageRoute<String> _internalCupertinoPageRoute;
AppPageRoute({
#required this.builder,
RouteSettings settings: const RouteSettings(),
this.maintainState: true,
bool fullscreenDialog: false,
}) : assert(builder != null),
assert(settings != null),
assert(maintainState != null),
assert(fullscreenDialog != null),
super(
settings: settings,
fullscreenDialog: fullscreenDialog,
builder: builder,
) {
assert(opaque); // PageRoute makes it return true.
}
#override
Color get barrierColor => null;
#override
Duration get transitionDuration => const Duration(milliseconds: 1000);
CupertinoPageRoute<String> get _cupertinoPageRoute {
assert(_useCupertinoTransitions);
_internalCupertinoPageRoute ??= new CupertinoPageRoute<String>(
builder: builder,
fullscreenDialog: fullscreenDialog,
hostRoute: this,
);
return _internalCupertinoPageRoute;
}
bool get _useCupertinoTransitions {
return _internalCupertinoPageRoute?.popGestureInProgress == true ||
Theme.of(navigator.context).platform == TargetPlatform.iOS;
}
#override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
final Widget result = builder(context);
assert(() {
if (result == null) {
throw new FlutterError('The builder for route "${settings.name}" returned null.\n'
'Route builders must never return null.');
}
return true;
}());
return result;
}
#override
Widget buildTransitions(
BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
if (_useCupertinoTransitions) {
return _cupertinoPageRoute.buildTransitions(context, animation, secondaryAnimation, child);
}
return new _CustomPageTransition(routeAnimation: animation, child: child, fullscreenDialog: fullscreenDialog);
}
}
class _CustomPageTransition extends StatelessWidget {
final Animation<Offset> _positionAnimation;
final Widget child;
final bool fullscreenDialog;
_CustomPageTransition({
Key key,
#required Animation<double> routeAnimation,
#required this.child,
#required this.fullscreenDialog,
}) : _positionAnimation = !fullscreenDialog
? _kRightMiddleTween.animate(new CurvedAnimation(
parent: routeAnimation,
curve: Curves.elasticIn,
))
: _kBottomUpTween.animate(new CurvedAnimation(
parent: routeAnimation, // The route's linear 0.0 - 1.0 animation.
curve: Curves.elasticIn,
)),
super(key: key);
#override
Widget build(BuildContext context) {
return new SlideTransition(
position: _positionAnimation,
child: child,
);
}
}
Push new Route
Future goToHomePage() async {
await new Future.delayed(const Duration(milliseconds: 4000));
Navigator.of(context).push(new AppPageRoute(builder: (BuildContext context) => new HomePage()));
}
You can use Custom MaterialPageRoute for the splash screen and for other routes MaterialPageRoute.
Hope it helps
// main.dart class
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
import 'package:flutter_test7/photo_hero.dart';
import 'package:flutter_test7/second_page.dart';
class HeroAnimation extends StatelessWidget {
Widget build(BuildContext context) {
timeDilation = 2.5; // 1.0 means normal animation speed.
return new Scaffold(
appBar: new AppBar(
title: const Text('Basic Hero Animation'),
),
body: new Center(
child: new PhotoHero(
photo: 'images/flippers-alpha.png',
width: 300.0,
onTap: () {
Navigator.of(context).pushNamed('/second_page');
},
),
),
);
}
}
void main() {
runApp(
new MaterialApp(
home: new HeroAnimation(),
routes: <String, WidgetBuilder>{
'/second_page': (context) => new SecondPage()
},
),
);
}
// photo_hero.dart class
import 'package:flutter/material.dart';
class PhotoHero extends StatelessWidget {
const PhotoHero({Key key, this.photo, this.onTap, this.width})
: super(key: key);
final String photo;
final VoidCallback onTap;
final double width;
Widget build(BuildContext context) {
return new SizedBox(
width: width,
child: new Hero(
tag: photo,
child: new Material(
color: Colors.transparent,
child: new InkWell(
onTap: onTap,
child: new Image.asset(
photo,
fit: BoxFit.contain,
),
),
),
),
);
}
}
// second_page.dart class
import 'package:flutter/material.dart';
import 'package:flutter_test7/photo_hero.dart';
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => new _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text('Flippers Page'),
),
body: new Container(
color: Colors.lightBlueAccent,
padding: const EdgeInsets.all(16.0),
alignment: Alignment.topLeft,
child: new PhotoHero(
photo: 'images/flippers-alpha.png',
width: 100.0,
onTap: () {
Navigator.of(context).pop();
},
),
),
);
}
}
Hope this helps.
Hero animation is quite easy to implement in Flutter. You just need to import the package package:flutter/scheduler.dart in your landing page. See below code
import 'package:flutter/scheduler.dart' show timeDilation;
Remember to add timeDilation variable and assign it a value to speed up or slow down the animation in seconds. Add these just after your build method as in example below
Widget build(BuildContext context) {
timeDilation = 2;
For better animation, just use a custom animation

Resources