Load an image with either JPG extension or PNG one - flutter

In my Flutter app, I return asset (product image) name by:
class Product {
// ...
final int id;
// ...
String get assetName => '$id-0.jpg';
}
And later, I use the asset name like:
// ...
image: AssetImage(product.assetName),
// ...
Now, the problem is some of the images are *.jpg and some are *.png like:
Is there a way to tell the Flutter image loader to try to load '$id-0.jpg' and if the file doesn't exist, then try to load '$id-0.png'? Perhaps I can do that with regular expressions, but I cannot figure out how.

You can determine if an asset exists with rootBundle.load and a try-catch block. rootBundle.load will throw an exception if the asset is not found.
ByteData image;
try{
image = await rootBundle.load(assetNameHere.jpg);
}
catch(e) {
image = await rootBundle.load(assetNameHere.png);
}
I don't know the exception that this will throw on the asset not existing, so I can't tell you which error to catch on, but you can figure that out and modify your code to only do the png code on that exception type instead of everything.
With this method, since you're already forced to load the image into memory, you can store the ByteData and use MemoryImage instead of AssetImage.

Related

Flutter Image form Image Picker to Document Path

I am creating an app that saves images locally through sqflite, I have soon found out that the images are being saved as temp which means that it will be deleted by the device and i'm not able to retrieve those images anymore. I have been coding to save it to the document directory of the app but it seems to fail and throw error
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: FileSystemException: Cannot copy file to '/data/user/0/com.example.e4psmap/cache/scaled_0d5d5070-70da-4f42-9055-c31a6ed8d3d51761448072222030817.jpg', path = '/data/user/0/com.example.e4psmap/app_flutter/scaled_0d5d5070-70da-4f42-9055-c31a6ed8d3d51761448072222030817.jpg' (OS Error: No such file or directory, errno = 2)
this is my code:
void getpic(ImageSource src) async{
Uint8List byte;
final picfile = await _imagepicker.getImage(
source: src, imageQuality: 25
);
if(picfile != null){
Directory appDir = await getApplicationDocumentsDirectory();
String appdoc = appDir.path;
final filename = path.basename(picfile.path);
final local = File('${appdoc}/$filename');
final lclfile = await local.copy(picfile.path);
}
// converted = picfile!.path;
// setState(() {
// _imgfile = picfile!;
// });
Navigator.pop(context);
}
Anyone knows why I am having this errors, and any fix for this error, Thank you
The copy() function expects the source file to be passed as an argument, but in your code, you're passing picfile.path instead of the File object.
try to replace local.copy(picfile.path) with picfile.saveTo(local.path), which should save the image to the desired directory.
If you replace final with the corresponding class, the error will be very obvious.

flutter image picker reduce file size with provider and flutter_image_compress

I am using image picker to pick image from device(App) and after that stored that file in provider class like that.
File? _img;
get img=> _img;
void putbannerimg(File img) {
_img = img;
notifyListeners();
}
I found out that image picker does not compress png images, I tried compressing it with flutter_image_compress
compressFile() async {
final formservice = Provider.of<PostForm>(context, listen: false);
File file = formservice.bannerfile;
final result = await FlutterImageCompress.compressWithFile(
file.absolute.path,
quality: 54,
);
formservice.putbannerimg(File.fromRawPath(result!));
}
I tried this way And other multiple ways but getting different different errors I want to upload this file in firebase storage like this
var task = storageicon.putFile(formservice.iconfile);
please tell me where I am going wrong, without compress file all things are working fine
Edit: I found out that path should be a string how can I parse local code file in that
If you are using the "flutter_image_compress" package
You may have to use the compress function for files stored on the phone like this:
Future<File> testCompressAndGetFile(File file, String targetPath) async {
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path, targetPath,
quality: 88,
rotate: 180,
);
print(file.lengthSync());
print(result.lengthSync());
return result;
}
"compressAndGetFile()" returns a file while "compressWithFile()" returns a Uint8List.
If i understand your last question right, you want to use an image built into your application by default.
For this, you have to open your "pubsepc.yaml", go to the "flutter:" mark and add "assets:" like so:
flutter:
assets:
- path
"path", in my example, describes a top level folder containing assets like pictures.
You can freely describe its name.

How to display Cover Image of an epub file in Flutter

The dart-epub plugin mentions an example on how to get Cover Image:
// Book's cover image (null if there is no cover)
Image coverImage = epubBook.CoverImage;
How can I display this? I keep getting an error
The following _TypeError was thrown building:
type 'Image' is not a subtype of type 'ImageProvider<Object>'
Update: I figured it out
Import the image and epub package as
import 'package:image/image.dart' as image;
import 'package:epub/epub.dart' as epub;
Open the epub file
// Change the location to wherever your epub file is located
var targetFile = new File('location/epubFile.epub');
List<int> bytes = await targetFile.readAsBytes();
epub.EpubBook epubBook = await epub.EpubReader.readBook(bytes);
Save the Cover Image to some location (ideally same folder as the epub file so it easier to delete together)
// Save the Cover Image to some location
if (await File('location/epubFileCoverImage.png').exists()) {
print("File exists");
} else {
try {
File('location/epubFileCoverImage.png')
.writeAsBytesSync(image.encodePng(epubBook.CoverImage));
} catch (e) {
print("Error Saving Cover Image");
print(e);
coverError = true;
}
}
Use Exception handling as there may be errors loading the Cover Image for some epub files
Finally to display it in the Widget tree:
coverError ? Image.asset("assets/Error.png")
: Image.file(File('location/epubFileCoverImage.png')),

How to record a video with Camera Plugin in flutter?

I have this page where the camera is initialized and ready with a button that will record and stop the video, so I tried this :
FlatButton(
onPressed: () => {
!isRecording
? {
setState(() {
isRecording = true;
}),
cameraController.prepareForVideoRecording(),
cameraController.startVideoRecording('assets/Videos/test.mp4')
}
: cameraController.stopVideoRecording(),
},
............
but throws this error : nhandled Exception: CameraException(videoRecordingFailed, assets/Videos/test.mp4: open failed: ENOENT (No such file or directory)).
I don't understand, I don't want to open this file I want to save it there, Is there sth wrong with my code ?
In the new version, static method startRecordingVideo doesn't take any string parameter.
When you want to start the recording just see whether a video is already getting recorded, if not start
if (!_controller.value.isRecordingVideo) {
_controller.startVideoRecording();
}
and when you want to finish the recording you can call the static method stopVideoRecording() and it will give you a object of the class XFile, it will have the path to your video.
if (_controller.value.isRecordingVideo) {
XFile videoFile = await _controller.stopVideoRecording();
print(videoFile.path);//and there is more in this XFile object
}
This thing has worked for me. I am new to flutter please improve my answer if you know more.
You are trying to save a video in your assets folder which is not possible ,
What you need to do is to save to device locally either common folders like downloads or app directory.
Here is an example of how to go about it
dependencies:
path_provider:
Flutter plugin for getting commonly used locations on host platform
file systems, such as the temp and app data directories.
We will be saving the video to app directory.
We need to get the path to the directory where the file is or will be. Usually a file is put in the application's document directory, in the application's cache directory, or in the external storage directory. To get the path easily and reduce the chance of type, we can use PathProvider
Future<String> _startVideoRecording() async {
if (!controller.value.isInitialized) {
return null;
}
// Do nothing if a recording is on progress
if (controller.value.isRecordingVideo) {
return null;
}
//get storage path
final Directory appDirectory = await getApplicationDocumentsDirectory();
final String videoDirectory = '${appDirectory.path}/Videos';
await Directory(videoDirectory).create(recursive: true);
final String currentTime = DateTime.now().millisecondsSinceEpoch.toString();
final String filePath = '$videoDirectory/${currentTime}.mp4';
try {
await controller.startVideoRecording(filePath);
videoPath = filePath;
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
//gives you path of where the video was stored
return filePath;
}

In Flutter, How to detect the completion of copying file?

I am beginner on Flutter.
I want to do this process,,,
1. save a image file.
2. read the property information of the saved image file.
below is the code for it.
// save a image file.
String mainDir = await getMainDirectory(widget.topic);
String path = mainDir + '/' + count.toString();
image.copy(path);
ImageProperties properties;
try {
// get the property information of the image file.
properties = await FlutterNativeImage.getImageProperties( path);
}
on PlatformException catch(e) {
print( e );
// try again ...
properties = await FlutterNativeImage.getImageProperties(
path);
}
When this code running, sometimes an error is occurred.
the error message is "file is not exist".
So, I have to call "getImageProperties()" function again, and I can get the property.
If I can detect the completion of the file copy, I can make these code better.
Is there any suggestion ?
You can use await to make sure image copy finish
final File newImage = await image.copy(path);