Display Image from preferences in Flutter App - flutter

I am having a problem. I have a Drawer in Flutter App and I want to implement a feature where you can pick a photo from gallery. Thats the easy part. But i want to save this photo in the preferences and load it when the App starts again. The imageFromPreferences variable have to be an Future to use it in the preferenceImage() Future builder. I got not idea how to it after hours of research. Maybe its the total wrong approach and you got a different idea.
import 'dart:io';
import 'dart:ui';
import 'package:firstapp/database/database.dart';
import 'package:firstapp/views/note.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firstapp/Utility/Utility.dart';
class NoteList extends StatefulWidget {
#override
NoteListState createState() {
return new NoteListState();
}
}
class NoteListState extends State<NoteList> {
Future<File> imageFile;
Image imageFromPreferences;
pickImageFromGallery(ImageSource source) {
setState(() {
imageFile = ImagePicker.pickImage(source: source);
});
}
loadImageFromPreferences() {
Utility.getImageFromPreferences().then((img) {
setState(() {
imageFromPreferences = Utility.imageFromBase64String(img);
});
});
}
Widget preferenceImage() {
return FutureBuilder<Image>(
future: loadImageFromPreferences(),
builder: (BuildContext context, AsyncSnapshot<Image> image) {
print(image);
if (image.connectionState == ConnectionState.done && image.hasData) {
return image.data;
} else {
return Text("error");
}
},
);
}
Widget imageFromGallery() {
return FutureBuilder<File>(
future: imageFile,
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
Utility.saveImageToPreferences(
Utility.base64String(snapshot.data.readAsBytesSync()));
return Image.file(
snapshot.data,
);
}
return null;
},
);
}
finalPicker() {
if (imageFromGallery() == null) {
return preferenceImage();
} else if (imageFromGallery() != null) {
return imageFromGallery();
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Taking Notes')),
drawer: Drawer(
child: ListView(
children: <Widget>[
UserAccountsDrawerHeader(
accountEmail: Text('lala#web.de'),
accountName: Text('Max'),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
),
currentAccountPicture: GestureDetector(
onTap: () {
pickImageFromGallery(ImageSource.gallery);
},
child: Column(
children: <Widget>[finalPicker()],
),
),
),
Container(
padding: EdgeInsets.all(20.0),
child: Text("Locked files"),
color: Theme.of(context).primaryColor,
),
],
),
),
This is how I save the Image as a String in the preferences. Maybe I could instead save it in a file?
import 'dart:async';
import 'dart:convert';
class Utility{
static const String IMG_KEY = "IMAGE_KEY";
static Future<bool> saveImageToPreferences(String value) async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.setString(IMG_KEY, value);
}
static Future<String> getImageFromPreferences() async{
final SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getString(IMG_KEY);
}
static String base64String(Uint8List data) {
return base64Encode(data);
}
static Image imageFromBase64String(String base64String){
return Image.memory(base64Decode(base64String), fit: BoxFit.fill);
}
}

// using your method of getting an image
final File image = await ImagePicker.pickImage(source: imageSource);
// getting a directory path for saving
final String path = await getApplicationDocumentsDirectory().path;
// copy the file to a new path
final File newImage = await image.copy('$path/image1.png');
setState(() {
_image = newImage;
});
you can store this path in your shared preference.
here you make copy in root directory and then store path of that image.

also you can used this plugin
https://pub.dev/packages/image_picker_saver
[image_picker_saver][1]

Related

StateError (Bad state: Cannot emit new states after calling close) in bloc_base.dart

I need your help. Just an hour ago this code worked fine, but now I get the error you see in the question
The bottom line is that when I click on the button, I go to the screen where I have to scan the qr code, but when I go to this very screen, I get an error. Help fix it!
Full screen code posted below -
import 'dart:developer';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_cubit.dart';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_state.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart';
// import 'package:mobile_scanner/mobile_scanner.dart';
import 'dart:io';
import '../home/home.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class QRViewExample extends StatefulWidget {
#override
_QRViewExampleState createState() => _QRViewExampleState();
}
class _QRViewExampleState extends State<QRViewExample> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
#override
void reassemble() {
super.reassemble();
print('первая функция');
if (Platform.isAndroid) {
controller!.pauseCamera();
} else if (Platform.isIOS) {
controller!.resumeCamera();
}
}
getQr(qr) {
if (qr != null) {
RegExp exp = RegExp(r"[^0-9]+");
final stringFormat = qr.code.rawContent.replaceAll(exp, '');
return stringFormat;
}
}
#override
Widget build(BuildContext context) {
return BlocProvider<ScannerCubit>(
create: (context) => ScannerCubit(),
child: BlocBuilder<ScannerCubit, ScannerState>(
builder: (context, state) {
if (state is ScannerNotScan) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 5,
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
),
),
Expanded(
flex: 1,
child: Center(
child: (result != null)
? Text(
'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
: Text('Scan a code'),
),
)
],
),
);
} else if (state is ScannerLoading) {
return Scaffold(
body: Center(child: CircularProgressIndicator()),
);
} else if (state is ScannerLoaded) {
return Home();
} else if (state is ScannerError) {
return Scaffold(
body: Center(child: Text('4')),
);
}
throw StateError('err');
},
),
);
}
void _onQRViewCreated(QRViewController controller) async {
print('последняя функция');
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
if (result != null) {
getNextScreen();
}
});
});
}
void getNextScreen() async {
if (result != null) {
await context.read<ScannerCubit>().scanner(getQr(result!.code));
// log(await getQr(result!.code.toString()));
}
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
}
and my cubit -
import 'dart:convert';
import 'dart:developer';
import 'package:eco_city/features/data/scanner/scanner_models.dart';
import 'package:eco_city/features/presentation/scanner/cubit/scanner_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import '../../config.dart';
class ScannerCubit extends Cubit<ScannerState> {
ScannerCubit() : super(ScannerNotScan());
Future<void> scanner(String qr) async {
emit(ScannerLoading());
final prefs = await SharedPreferences.getInstance();
final token = prefs.getString('token');
final response = await http.post(Uri.parse(ConfigUrl.sendQrCodeScanner),
headers: {
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": "Bearer $token"
},
body: jsonEncode(<String, dynamic>{
"qr_code": qr,
}));
if(isClosed) return;
if (response.statusCode == 200) {
log(qr);
final responseJson = json.decode(response.body) as Map<String, dynamic>;
emit(ScannerLoaded(scannerModel: ScannerModel.fromJson(responseJson)));
} else {
log(qr);
log(response.statusCode.toString());
log(json.decode(response.body).toString());
emit(ScannerError());
}
}
}
Sometimes my screen is replaced well, but often with an error
you shouldn't place the BlocProvider inside the stateful widget. Like this, the provider becomes re-created on every new build, for example if the scan provides no result.
Try to create an upstream widget (above QRViewExample) and place the provider there.

error when using File with ImagePicker Flutter

The error is with this line: File selectedImage
I only have dart.io imported, not even dart.html so I'm not sure why I'm getting this error.
here is the longer piece of code
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:random_string/random_string.dart';
import 'package:tennis_event_app/services/crud.dart';
class CreateBlog extends StatefulWidget {
#override
_CreateBlogState createState() => _CreateBlogState();
}
class _CreateBlogState extends State<CreateBlog> {
late String pass, authorName, title, desc;
File selectedImage;
final picker = ImagePicker();
bool _isLoading = false;
CrudMethods crudMethods = new CrudMethods();
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
selectedImage = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
(this is not the entire code but just a larger piece)
What exact error are you getting?
Suggestion
Please do well to put setState((){...}); in the if-statement like this:
if(pickedFile != null){
setState((){
selectedImage = File(pickedFile.path);
});
}else{
print('No image selected');
}
and Hot Reload.
SEE COMPLETE SOLUTION THAT WORKED FOR ME
class _ImageSelectorState extends State<ImageSelector> {
var imageFile;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 200.0,
height: 200.0,
color: Colors.grey.shade300,
child: imageFile != null
? Image.file(imageFile)
: Icon(
Icons.image,
),
),
SizedBox(height: 20.0),
//Button
Center(
child: ElevatedButton(
onPressed: _pickImage,
child: Text('Upload Image'),
),
),
],
),
);
}
_pickImage() async {
try {
final picker = await ImagePicker().getImage(
source: ImageSource.gallery,
);
if (picker != null) {
setState(() {
imageFile = File(picker.path);
});
}
} catch (e) {
print(e);
}
}
}
Result
Solution I Used:
I ended up changing File selectedImage; to File ? selectedImage;

Is their any way to convert .jpeg images to .gif in flutter?

Like my title, is there anyway to convert images to a video in flutter? (It doesn't have to be .gif necessarily)
To be more specific, I am using Google Firebase as my storage cloud server to upload pictures taken by camera plugin of flutter.
I want to convert my images to a video so that it looks like a time-lapse video.
Any advice would be nice.
===============================
the pictures are taken by camera plugin which uses camera.dart, and it is stored it firebase storage like this:
onCapture(context) async {
try {
final p = await getTemporaryDirectory();
var now = DateTime.now();
var formattedDate = DateFormat('yy-MM-dd HH:mm:ss').format(now);
final path = '${p.path}/$now.png';
await cameraController.takePicture(path).then((value) {
print('here');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PreviewScreen(
imgPath: path,
fileName: '$formattedDate.png',
pickedTime: '$formattedDate',
)));
});
} catch (e) {
showCameraException(e);
}
}
========================================
edit :
Before constructing gif, i am having trouble downloading an image from firebase and putting this image on the canvas. I think I can use your code to make a gif once I do this.
import 'dart:io';
import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as IMG;
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
import 'package:firebase_core/firebase_core.dart' as firebase_core;
import 'package:provider/provider.dart';
import 'package:weighit/models/user_info.dart';
class ToGif extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Timelapse Video'),
),
body: Container(
child: Thumbnail(),
),
);
}
}
class Thumbnail extends StatefulWidget {
const Thumbnail({Key key}) : super(key: key);
#override
_ThumbnailState createState() => _ThumbnailState();
}
class _ThumbnailState extends State<Thumbnail> {
List<int> imgBytes;
Isolate isolate;
File image;
#override
void initState() {
_asyncInit();
super.initState();
}
static _isolateEntry(dynamic d) async {
final ReceivePort receivePort = ReceivePort();
d.send(receivePort.sendPort);
final config = await receivePort.first;
print(config);
final file = File(config['path']);
final bytes = await file.readAsBytes();
IMG.Image image = IMG.decodeImage(bytes);
IMG.Image thumbnail = IMG.copyResize(
image,
width: config['size'].width.toInt(),
);
d.send(IMG.encodeNamedImage(thumbnail, basename(config['path'])));
}
_asyncInit() async {
final receivePort = ReceivePort();
isolate = await Isolate.spawn(_isolateEntry, receivePort.sendPort);
receivePort.listen((dynamic data) {
if (data is SendPort) {
if (mounted) {
data.send({
'path': image.path,
'size': Size(500, 500),
});
}
} else {
if (mounted) {
setState(() {
imgBytes = data;
});
}
}
});
}
#override
void dispose() {
if (isolate != null) {
isolate.kill();
}
super.dispose();
}
// Download on DocumnetDirectory, not temporary directory https://flutter-ko.dev/docs/cookbook/persistence/reading-writing-files
Future<void> downloadFileExample() async {
final appDocDir = await getApplicationDocumentsDirectory();
image = File('${appDocDir.path}/download-logo.png');
try {
await firebase_storage.FirebaseStorage.instance
// can not find proper reference path...
.ref('gs://weighit-f506b.appspot.com/guny/21-04-26 10:56:21.png')
.writeToFile(image);
} on firebase_core.FirebaseException catch (e) {
print('couldnt find the reference');
}
}
#override
Widget build(BuildContext context) {
final _user = Provider.of<TheUser>(context);
return FutureBuilder(
future: downloadFileExample(),
builder: (context, snapshot) {
//해당 부분은 data를 아직 받아 오지 못했을때 실행되는 부분을 의미한다.
if (snapshot.hasData == false) {
return Center(child: CircularProgressIndicator());
}
//error가 발생하게 될 경우 반환하게 되는 부분
else if (snapshot.hasError) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Error: ${snapshot.error}',
style: TextStyle(fontSize: 15),
),
);
} else {
return SizedBox(
height: 500,
width: 500,
child: imgBytes != null
? Image.memory(
imgBytes,
fit: BoxFit.cover,
)
: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.grey[100], Colors.grey[300]],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
),
);
}
},
);
}
}
You can use the image package to created animated GIFs from multiple images.
First add it as a dependency:
dependencies:
image: ^3.0.2
Then to you can make a function to generate an animated GIF from multiple images:
List<int>? generateGIF(Iterable<Image> images) {
final Animation animation = Animation();
for(Image image in images) {
animation.addFrame(image);
}
return encodeGifAnimation(animation);
}
To use this function with multiple images that are in files from the camera package in the form of XFiles, you have to decode the images for each of those files and pass it to this function. The following code assumes you know that these are JPEG images:
List<XFile> imageFiles = ...;
final JpegDecoder decoder = JpegDecoder();
final List<Image> images = [];
for(var imgFile in imageFiles) {
Uint8List data = await imgFile.readAsBytes();
images.add(decoder.decodeImage(data));
}
List<int>? gifData = generateGIF(images);

how to make string as global variable in flutter

I was create SharedPreferences to save user loading in logon page. Then data of user will be save in SharedPreferences and move to main page. But my problem now in main page I need use this variable in different places in main page. But I cant do that.
I need to make variable of logindata can use in each places in main page I try to use in drawer to make logout. No I get error as:
Undefined name 'logindata'.
this is my code:
void initial() async {
logindata = await SharedPreferences.getInstance();
setState(() {
username = logindata.getString('username');
return username;
});
}
my full code:
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'addnewtopics.dart';
import 'DetilesOfMainPage.dart';
import 'loginpage.dart';
class MyApp extends StatelessWidget {
final String email;
MyApp({Key key, #required this.email}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('JSON ListView')
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
logindata.setBool('login', true);// here I need to use It ========================
Navigator.pushReplacement(context,
new MaterialPageRoute(builder: (context) => LoginUser()));
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
// Navigator.pop(context);
},
),
],
),
),
body: JsonImageList(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => UploadImageDemo()
),);
},
child: Icon(Icons.add),
),
));
}
}
class Flowerdata {
int id;
String flowerName;
String flowerImageURL;
Flowerdata({
this.id,
this.flowerName,
this.flowerImageURL
});
factory Flowerdata.fromJson(Map<String, dynamic> json) {
return Flowerdata(
id: json['id'],
flowerName: json['nametopics'],
flowerImageURL: json['image']
);
}
}
class JsonImageList extends StatefulWidget {
JsonImageListWidget createState() => JsonImageListWidget();
}
class JsonImageListWidget extends State {
SharedPreferences logindata;
String username;
#override
void initState() {
// TODO: implement initState
super.initState();
initial();
}
void initial() async {
logindata = await SharedPreferences.getInstance();
setState(() {
username = logindata.getString('username');
return username;
});
}
final String apiURL = 'http://xxxxxxxxx/getFlowersList.php';
Future<List<Flowerdata>> fetchFlowers() async {
var response = await http.get(apiURL);
if (response.statusCode == 200) {
final items = json.decode(response.body).cast<Map<String, dynamic>>();
List<Flowerdata> listOfFruits = items.map<Flowerdata>((json) {
return Flowerdata.fromJson(json);
}).toList();
return listOfFruits;
}
else {
throw Exception('Failed to load data from Server.');
}
}
getItemAndNavigate(String item, BuildContext context){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(itemHolder : item)
)
);
}
#override
Widget build(BuildContext context) {
return FutureBuilder<List<Flowerdata>>(
future: fetchFlowers(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Center(
child: CircularProgressIndicator()
);
return ListView(
children: snapshot.data
.map((data) => Column(children: <Widget>[
GestureDetector(
onTap: ()=>{
getItemAndNavigate(data.flowerName, context)
},
child: Row(
children: [
Container(
width: 200,
height: 100,
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child:
Image.network(data.flowerImageURL,
width: 200, height: 100, fit: BoxFit.cover,))),
Flexible(child:
Text(data.flowerName,
style: TextStyle(fontSize: 18)))
]),),
Divider(color: Colors.black),
],))
.toList(),
);
},
);
}
}
Anyone know how can make that?
You need var keyword, in your case you can directly use
var logindata = await SharedPreferences.getInstance();
You do not need to make it global, because SharedPreferences.getInstance() is Singleton
Every time you use var logindata = await SharedPreferences.getInstance(); will get the same instance
Also there is no performance issue when you call getInstance(), because it's cached, you can see source code snippet below
class SharedPreferences {
SharedPreferences._(this._preferenceCache);
...
static Future<SharedPreferences> getInstance() async {
if (_completer == null) {
_completer = Completer<SharedPreferences>();
try {
final Map<String, Object> preferencesMap =
await _getSharedPreferencesMap();
_completer.complete(SharedPreferences._(preferencesMap));
} on Exception catch (e) {
// If there's an error, explicitly return the future with an error.
// then set the completer to null so we can retry.
_completer.completeError(e);
final Future<SharedPreferences> sharedPrefsFuture = _completer.future;
_completer = null;
return sharedPrefsFuture;
}
}
return _completer.future;
When you declare a String outside of class and does not contain _ before variable name like _localString it become global
String globalString = ""; //global, import can be seen
String _localString = ""; //local and can only be seen in this file, import can not seen
void main() async{
var logindata = await SharedPreferences.getInstance();
runApp(MyApp());
}
You simply need to put your variable outside of any class or method. An example is to create a file globals.dart then put all your globals in it and import the file when you need.
Example
// globals.dart
String globalString;
int globalInt;
bool globalBool;
// in any other file
import 'globals.dart' as globals;
globals.globalString = "Global String";

Flutter Image Widget won't update on change state

I am creating an Image Editor application using sliders, something like Instagram, and I am using library image/image.dart.
The problem is that once you move the slider it updates the image but just that time, if you move it again, it won't update.
I have set everything as expected, setState() functions as flutter asks, but I don't know why it won't update again.
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as br;
import 'package:path_provider/path_provider.dart';
import 'package:image_picker/image_picker.dart';
class ImageManager extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _ImageManagerState();
}
}
class _ImageManagerState extends State<ImageManager> {
File imageFile;
br.Image image;
Image _imageWidget;
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
// get tmp file
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/tmp.jpg');
}
// pick image on button click
Future<void> _pickImage(ImageSource source) async{
File selectedFile = await ImagePicker.pickImage(source: source);
br.Image selectedImage;
if (selectedFile != null){
selectedImage = br.decodeImage(selectedFile.readAsBytesSync());
br.grayscale(selectedImage);
selectedFile.writeAsBytesSync(br.encodeJpg(selectedImage));
}
setState((){
image = selectedImage;
imageFile = selectedFile;
_imageWidget = Image.file(imageFile);
});
}
// MAIN PROBLEM, UPDATING THE CONTRAST WILL ONLY DO IT ONCE
Future<void> updateContrast(value) async{
File contrastFile = imageFile;
br.Image contrast = br.decodeImage(contrastFile.readAsBytesSync());
contrast = br.adjustColor(contrast, contrast: value);
contrastFile.writeAsBytesSync(br.encodeJpg(contrast));
// Save the thumbnail as a jpg.
File path = await _localFile;
path.writeAsBytesSync(br.encodeJpg(contrast));
setState(() {
image = contrast;
imageFile = contrastFile;
if(path != null){
_imageWidget = Image.file(path);
print(value);
}
});
}
//
Widget _buildImage(BuildContext context){
return Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
child: _imageWidget,
),
Column(
children: [
Container(
padding: const EdgeInsets.only(left: 8, right: 8),
child: Column(
children: <Widget>[
// contrast
Text("Contraste"),
Padding(
padding: const EdgeInsets.only(bottom: 4.0, top: 0.0),
child: Container(
child: Slider(
min: 0.0,
max: 1.0,
divisions: 100,
value: _contrast,
activeColor: Colors.blue[500],
inactiveColor: Colors.blue[50],
label: "${(_contrast *100).round()}",
onChanged: (value) async{
changeContrast(value);
},
onChangeEnd: (value) async{
updateContrast(value);
},
),
),
),
],
),
),
],
),
]
);
}
I expect the image to update every time the slider is changed.
imageCache.clear() will do the job.
I was also not able to reload the image to save locally on the screen. From debugging, I observed the old image is in fact deleted, and new image is copied there, but nothing was changing on the screen. Following is the code you need.
So, in the body of Scaffold, I have made a FutureBuilder that calls another function reload(), which then loads the file and return the image.
FutureBuilder(
future: reload(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if(snapshot.connectionState == ConnectionState.done){
return snapshot.data;
}
else{
return CircularProgressIndicator();
}
},
),
Here is the reload() function:
reload() async {
String path = "path of your image";
File profileImage = File("$path/name.jpg");
if(profileImage.existsSync() == false){
return Text("File Not Found");
}
else{
imageCache.clear();
return Image.file(profileImage);
}
}
I checked Flutter's github, and jamesncl has already suggested this.
I solved the issue, which is pretty weird to me, but if someone can explain it, I would appreciate it.
Future<void> adjustImage() async{
File toAdjustFile = imageFile;
br.Image toAdjust = br.decodeImage(toAdjustFile.readAsBytesSync());
toAdjust = br.adjustColor(toAdjust, contrast: _contrast, brightness: _brightness, exposure: _exposure);
setState(() {
_imageWidget = Image.memory(br.encodeJpg(toAdjust));
});
}
I refactored my function and set the widget to another constructor, Image.memory().
Use Image.memory instaead Image.file, A line from my code
Image.memory(
File(widget.imagePath).readAsBytesSync(),),