Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is local image file supported #478

Closed
eliranwong opened this issue Dec 31, 2020 · 15 comments
Closed

is local image file supported #478

eliranwong opened this issue Dec 31, 2020 · 15 comments

Comments

@eliranwong
Copy link

First, thanks for developing this useful package. Can you please advise me how the html codes work with local image files, e.g. images stored in user directory? In your example, I can see the image source is online. Is it possible to load image offline?

@salvaterra
Copy link

salvaterra commented Dec 31, 2020

<img src="asset:assets/graphics/art.png">

@eliranwong
Copy link
Author

thanks a lot for reply. It works in assets folder. Impressive!

How about if I want to load image file from user directory? what should I put in place of "asset:"?

for example, if I have an image with a full path, myUserDirectoryPath/graphics/art.png ?

@erickok
Copy link
Collaborator

erickok commented Jan 1, 2021

That would depend on where the image is. Unless it is in your own private app folder, you won't be able to directly refer to a file.

@eliranwong
Copy link
Author

I put image in shared user directory, accessible by users. The assets folder has a problem that I cannot pack the appbundle file and upload to google play store if the file is larger than 150 MB. I have image files, greater than 500MB. So, I need users to put in shared user directory and access image from there.

I got the user directory path by the following codes:

class StorageMx {

// Check if storage permission is granted.
static Future checkStoragePermission() async {
final permissionResult = await Permission.storage.request();
return (permissionResult.isGranted) ? true : false;
}

// get user directory
static Future getUserDirectoryPath() async {
if (await checkStoragePermission()) {
final Directory userDirectory = (Platform.isAndroid)
? await getExternalStorageDirectory()
: await getApplicationDocumentsDirectory();
return userDirectory.path;
} else {
return "";
}
}

}

@erickok
Copy link
Collaborator

erickok commented Jan 1, 2021

If these files are content your app needs to function, then you should not put them in external storage directory on Android.

@eliranwong
Copy link
Author

the images file are not necessary for my app to run.

I am writting a bible app. If users want additional bible maps, they can download to user directory. so the feature is optional. the app does not depends the image file to run.

I want to load those images with flutter_html. is that possible?

@ryan-berger
Copy link
Collaborator

@erickok This seems similar to previous issues that have been raised to add your own image URI resolver. I don't believe we have this now, so is this a duplicate of other issues that want to be able to resolve image URIs however they would like?

@erickok
Copy link
Collaborator

erickok commented Jan 4, 2021

Yes, I think a custom image resolver would... resolve these type of issues. Something to work on I guess because what the issue creator wants I believe is currently not possible (yet totally reasonable).

@ryan-berger
Copy link
Collaborator

Is accessing the filesystem not feasible in Flutter? On the Android side I thought you could set up a storage provider for your app so that you can write to the filesystem, and then when you want to load in images Flutter could fetch the bytes and you could render the raw image.

Also maybe such a fetch would be quite slow with Flutter? Communication between Flutter/Native seems to be something that should be done as little as possible with as little data as possible and isn't built for something larger like image transfer, but most of the Flutter apps I've built don't require much and are mostly just API calls and nothing too Native.

If this really isn't possible and you can't get images from the filesystem with Flutter (for iOS or Android) then I think that the issue should be closed due to it being infeasible.

Otherwise, lets create a new issue or find the "file resolver" issue and reference this issue there so when it gets closed we can close this one as well. I think that it would be a really good feature to have and something that I could look into and shouldn't be to hard to implement

@eliranwong
Copy link
Author

Thanks a lot for replies. If local image in shared directory cannot be read directly, can I first covert it to base64 and put in img tag. Does flutter_html support base64 String.

@erickok
Copy link
Collaborator

erickok commented Jan 5, 2021

The problem isn't that you can't read files of course on Android. But depending on where the files are and who owns them you can or cannot directly access them via the normal IO. For example, if a photo gets shared to your app, you'll just get a stream handle, and not get an actual file handle.

If you, like the OP, want to download additional (non-elemental) content on the fly, to augment the user experience, I still highly recommend downloading to the apps' protected own storage. This isn't data that you want to share with other apps (logically, regardless of security) and your app can access these files without difficulty.

For flutter_html, we'd still need a mechanism where you can tell how to resolve images. At the moment we support the following:

  • data:image and base64, for base64-encoded image data (you could already use this for your use-case right now)
  • asset: via Flutter's Image.asset widget
  • any other href will be loaded via Flutter's Image.network (wrapped in a FutureBuilder)

You can already override loading of images altogether by using a customRenderer for img. We could add explicit support for file: and event content: url's to a friendlier user experience.

@Levy787
Copy link

Levy787 commented Jan 6, 2021

I'm trying to use the local asset file

<img src="asset:assets/images/retro_logo.png">

but getting a URI error,

The following ArgumentError was thrown resolving an image codec:
Invalid argument(s): No host specified in URI file:///assets/images/logo_retro.png

When the exception was thrown, this was the stack: 
#0      _HttpClient._openUrl (dart:_http/http_impl.dart:2407:9)
#1      _HttpClient.getUrl (dart:_http/http_impl.dart:2328:48)
#2      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:89:59)
#3      NetworkImage.load (package:flutter/src/painting/_network_image_io.dart:50:14)
#4      ImageProvider.resolveStreamForKey.<anonymous closure> (package:flutter/src/painting/image_provider.dart:504:13)
...
Image provider: NetworkImage("assets/images/logo_retro.png", scale: 1.0)
Image key: NetworkImage("assets/images/logo_retro.png", scale: 1.0)

It seems like even with the asset: at the the beginning of the img src, it's still trying to get a NetworkImage.

@Levy787
Copy link

Levy787 commented Jan 6, 2021

I'm trying to use the local asset file

<img src="asset:assets/images/retro_logo.png">

but getting a URI error,

The following ArgumentError was thrown resolving an image codec:
Invalid argument(s): No host specified in URI file:///assets/images/logo_retro.png

When the exception was thrown, this was the stack: 
#0      _HttpClient._openUrl (dart:_http/http_impl.dart:2407:9)
#1      _HttpClient.getUrl (dart:_http/http_impl.dart:2328:48)
#2      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:89:59)
#3      NetworkImage.load (package:flutter/src/painting/_network_image_io.dart:50:14)
#4      ImageProvider.resolveStreamForKey.<anonymous closure> (package:flutter/src/painting/image_provider.dart:504:13)
...
Image provider: NetworkImage("assets/images/logo_retro.png", scale: 1.0)
Image key: NetworkImage("assets/images/logo_retro.png", scale: 1.0)

It seems like even with the asset: at the the beginning of the img src, it's still trying to get a NetworkImage.

For anyone having this issue, be sure to give your app a hot restart, it should work fine then.

@erickok
Copy link
Collaborator

erickok commented Jan 15, 2021

Identical request to #304. Let's discuss in #497 on an API that would suit you.

@erickok
Copy link
Collaborator

erickok commented Feb 8, 2021

With #505 merged you could already do this fairly easily. For example:

  // Some path to where your images are
  final localRoot = "/app/accessible/path/to/images";

  // Handle all paths that start with a / and treat as local
    (attr, _) => attr["src"] != null && attr["src"].startsWith("/wiki"):
        (context, attr, element) {
      final file = File(localRoot + attr["src"]);
      return Image.file(file);
    },

I'm not sure if we need more first-party support beyond this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants