Show Local Images and Server Images ( with Caching) in Flutter - dart

I am trying to show the image in a Widget picked from Image-Gallery as well as from the Network loaded images.
CachedNetworkImage is working fine with Network-images but when I try to pass selected image from gallery it's not working.
CachedNetworkImage(
imageUrl: url,
placeholder: (context, url) => new CircularProgressIndicator(),
errorWidget: (context, url, error) => new Icon(Icons.error),
);
Please help me to show this.
Objective is to
1. Can load local images
2. Can load network images
3. Can show Cached images.
Thank you in advance.

You need to determine when you'd like to display local image and when to display image from network. If the network image needs to display the local copy once it has been downloaded, you can add a checker if that image file exist locally. Else, the image should be fetched from network/cache. You can use the imageId of the image URL to be the same identifier for the local image.
var imgUrlEndpoint = 'https://picsum.photos/250?image='
var imgId = '9';
var imgFile = File('path/to/file/$imgId.jpg');
// Check if image file exists
if(imgFile.exists()){
// Load image from storage
Image.file(imgFile);
} else {
// Load image from network
CachedNetworkImage(
imageUrl: '$imgUrlEndpoint$imgId',
placeholder: (context, url) => CircularProgressIndicator(),
);
}

Related

Loading image from url fails

I'm trying to load some icons from url using Coil. But it never shows on screen.
code:
Image(
painter = rememberAsyncImagePainter(icon),
contentDescription = "condition icon"
)
When I log the icon variable I got the url without problems:
icon: //cdn.weatherapi.com/weather/64x64/night/113.png
But the image doesn't appear on the screen, any help?
CoilImage(
imageModel = imageUrl,
// Crop, Fit, Inside, FillHeight, FillWidth, None
contentScale = ContentScale.Crop,
// shows a placeholder while loading the image.
placeHolder = ImageBitmap.imageResource(R.drawable.placeholder),
// shows an error ImageBitmap when the request failed.
error = ImageBitmap.imageResource(R.drawable.error)
)
This should work as a charm (link)
I solved this by adding https: before the url. It seems like Coil can't add this by default like it happens in the browser.

Is there way to fix the camera Functionality onto iOS using flutter?

The problem is accessing the camera on iPhone does not work. Trying access the camera on Android does work. Im building app using flutter which Im trying to make the app functional for both device. Every time I press on camera button. The app exit by itself. Im trying to send this picture to the firebase database. Doing this way won't let me access camera functionality for iOS.
I have tried to eliminate photo library functionality but that did not work. Camera before was working. The camera dependency is in Pubspec.yaml
Future getImage() async {
var tempimage = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
sampleimage = tempimage;
});
}
Future getLibraryImage() async {
var libraryimage = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
sampleimage = libraryimage;
});
}
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(9.0)),
onPressed: () { getImage(); },
child: Row(
children: [
Text(" Camera "),
Image.asset("images/camera.png", height: 15.0,),
],
),
),
),
),
You have to ask the permission to the user for using the camera.
For that, you can add these lines in Info.plist file in ios/Runner
<key>NSPhotoLibraryUsageDescription</key>
<string>Using the library for ...</string>
<key>NSMicrophoneUsageDescription</key>
<string>Using the mic for ...</string>
<key>NSCameraUsageDescription</key>
<string>Using the camera for ...</string>

How to reload a FileImage in Flutter

Let's say I have an image on the device's disk and load it on the screen providing its path to a FileImage.
I edit that image and save it on the same path expecting calling the setState(() {}) function will reload it. But it doesn't.
I tried clearing the image cache by calling imageCache.clear() function and also imageProvider.evict() but no difference.
If I close that page and open it again, I see the updated images.
I assume the images that are being displayed on the screen are in the memory, if my assumption is correct, how to reload it?
I know I'm a bit late, but I used this workaround:
_tmpImageFile.existsSync() ? Image.memory(
Uint8List.fromList(_tmpImageFile.readAsBytesSync()),
alignment: Alignment.center,
height: 200,
width: 200,
fit: BoxFit.contain,
) : Container(),
This is also working for me:
Image previewImage = Image.file(
File(scenePreviewFilename),
);
And when pressing a button or something just evict the cached image from imageCache like this:
setState(() {
imageCache.evict(previewImage.image, includeLive: true);
});
PS: I had some issues getting this to work(similar to the initial post) because I was generating the image in another thread and the image was loaded before it was generated, resulting in the imageCache appearing not to have an effect ... so make sure you are not in this race situation.
Already tested - Adding the both image cache commands will solve the problem.
imageCache.clear();
imageCache.clearLiveImages();
});
Would changing the key of the Image do the trick?
Set a key to the image
Image.file(
_imageFile,
key: _key,
fit: BoxFit.cover,
),
and change the key every time you change _imageFile, let's set it to timestamp for example
setState(() {
_imageFile = newImageFile;
_key = DateTime.now().millisecondsSinceEpoch;
});
This is a bit ugly workaround, but it works for me. Here we're resetting image cache + force reloading image from disk:
class _MyAppState extends State<MyApp> {
final imageKey = GlobalKey();
bool forceLoad = false;
#override
Widget build(BuildContext context) {
final app = MaterialApp(
home: Scaffold(
body: forceLoad
? Image.memory(currentFile.readAsBytesSync(), key: imageKey)
: Image.file (currentFile, key: imageKey),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.refresh),
onPressed: () async {
await (imageKey.currentWidget as Image).image.evict(); // reset cache for current image
setState(() {
forceLoad = true; // reloading current image from disk
});
},
)
)
);
forceLoad = false;
return app;
}
}
The other answers were missing step 2. Full explanation here.
call imageCache.clear(); and then imageCache.clearLiveImages(); when the new image needs to be reloaded.
Add a value key in the image widget to ensure the new image gets rebuilt
Image(image: FileImage(File(pathName)), key: ValueKey(File(pathName).lengthSync()))
The image should reload after.

Display images with cdvfile://* in img tag cordova

I'm using the cordova-plugin-camera to take a picture with these options:
quality: 100,
destinationType: Camera.DestinationType.NATIVE_URI,
sourceType: srcType,
encodingType: Camera.EncodingType.JPEG,
mediaType: Camera.MediaType.PICTURE,
allowEdit: false,
saveToPhotoAlbum: true,
correctOrientation: true
This is working and I get an URL / Path like this:
assets-library://asset/asset.JPG?id=FBA79210-5E65-4C9B-BF19-9F1169B777C0&ext=JPG
Then, I want to convert this path to a cdvfile:// to display the image in an tag.
window.resolveLocalFileSystemURL(imageURI, function(fileEntry) {
const url = fileEntry.toInternalURL()
})
This is also working and I get:
cdvfile://localhost/assets-library/asset/asset.JPG?id=FBA79210-5E65-4C9B-BF19-9F1169B777C0&ext=JPG
But the image is not rendered. I tried to add <access origin="cdvfile:*" /> in my config.xml but that's not working either. How can i get a valid path / url to display the image?
Best wishes,
Joeri
I had the same problem and managed to solve it with a different approach. After getting the cdvfile url I used Photo Library plugin to get the blob file through the getPhoto method passing the id present in the cdvfile url and with this in hand I got the img source working with the base64data as below:
photoLibrary.getPhoto('FBA79210-5E65-4C9B-BF19-9F1169B777C0').then((blob)=>{
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var base64data = reader.result;
img.src = base64data;
}
});
UPDATE
You can also use getThumbnail function to improve your page loading depending on the quality, size and quantity of photos you app is supposed to handle.

Angular UI Grid - how to add an image to the top of the exported PDF?

I'm using Angular UI Grid and I've tried to few ways to add an image (logo) to the top of the PDF document which gets exported.
I've had no luck with the implementations I've tried...
exporterPdfHeader: { text: "My Header", image: "<urlOfImage>" }
exporterPdfHeader: { text: "My Header", backgroundImage: "<urlOfImage>" }
exporterPdfHeader: { text: "My Header", backgroundImage: url("<urlOfImage>") }
Is this even possible to do?
Thanks in advance.
Can you add your image inside a custom html header using headerTemplate: 'header-template.html', in grid-options?
See example ui-grid tutorial
edit
OK, having looked at the source and docs for the export, there is nothing there about passing images in the header.
It does refer you to pdfMake
Images
This is simple. Just use the { image: '...' } node type.
JPEG and PNG formats are supported.
var docDefinition = {
content: [
{ // you'll most often use dataURI images on the browser side // if no width/height/fit is provided, the original size will be used image: 'data:image/jpeg;base64,...encodedContent...' },
{ // if you specify width, image will scale proportionally image: 'data:image/jpeg;base64,...encodedContent...', width: 150 },
{ // if you specify both width and height - image will be stretched image: 'data:image/jpeg;base64,...encodedContent...', width: 150, height: 150 },
{ // you can also fit the image inside a rectangle image: 'data:image/jpeg;base64,...encodedContent...', fit: [100, 100] },
{ // if you reuse the same image in multiple nodes, // you should put it to to images dictionary and reference it by name image: 'mySuperImage' },
{ // under NodeJS (or in case you use virtual file system provided by pdfmake) // you can also pass file names here image: 'myImageDictionary/image1.jpg' } ],
images: {
mySuperImage: 'data:image/jpeg;base64,...content...' } }
end of quote
So it looks like you were close.
Can you try a relative path from the root of your website wrapped in single quotes.
Had to write a custom export function to add page margins.
Plnkr
$scope.export = function() {
var exportColumnHeaders = uiGridExporterService.getColumnHeaders($scope.gridApi.grid, uiGridExporterConstants.ALL);
var exportData = uiGridExporterService.getData($scope.gridApi.grid, uiGridExporterConstants.ALL, uiGridExporterConstants.ALL, true);
var docDefinition = uiGridExporterService.prepareAsPdf($scope.gridApi.grid, exportColumnHeaders, exportData);
docDefinition.pageMargins = [40, 80, 40, 60];
if (uiGridExporterService.isIE() || navigator.appVersion.indexOf("Edge") !== -1) {
uiGridExporterService.downloadPDF($scope.gridOptions.exporterPdfFilename, docDefinition);
} else {
pdfMake.createPdf(docDefinition).open();
}
}
Image has to be provided as base 64 encoded, unless using Node.js (as per pdfmake library).
Otherwise, you may need to use a JavaScript function to download and convert an image to base 64.
References:
https://stackoverflow.com/a/37058202/2808230
pdfExport function in http://ui-grid.info/release/ui-grid.js
Found this as I was writing up this answer: Angular UI Grid - Exporting an image to a pdf

Resources