Closed pneves001 closed 6 years ago
Note that you are decoding a data:
-URI and not a normal Base64 encoded string, so the error you are getting is absolutely correct. To decode data:
-URI you can use Uri
class, for example like this:
final UriData data = Uri.parse(yourString).data;
print(data.isBase64); // Should print true
print(data.contentAsBytes()); // Would returns your image a Uint8List
You know that there is no documentation telling us this.
Could you clarify what exactly is missing from the documentation?
When you need to parse a URI then you need to use a Uri
class, which is documented here.
Base64Decoder is documented here where it explicitly says “Decoder for base64 encoded data.“
If you have any concrete ideas of how this documentation can be improved please feel free to make a suggestion here or send a PR improving the documentation.
Reference documentation is pretty useless when there are no examples to show us how the class is used. There are no docs to suggest that we use the Uri.parse class to process a base 64 encoded image. I just assumed I worked pretty much the same way it worked when I generated the image on the server but in reverse. I had actually removed the leading data tag from the image before I attempted to base64 decode the image. It still didn't work.
Thanks for the help. The Uri.parse function worked. I just wish the docs had more examples to show us how to use the API. I find issues like this all over the internet when it comes to using different api. It's always a crapshoot as to figuring out what some of these classes are for or even how to use them.
Did you solve this problem? Today i meet the same quuestion....
i have the same issue at using any html viewer library :/
invalid character at base64 image...
looks like there is newlines/spaces in base64 generated by outlook, this is issue of dart but flutter devs on github says that it is not supported characters in base64.
but every other technology works like a harm with it :) even html 🤣 what a kind of embarrassing explanation of issue :| and unprofessional approach to the subject https://github.com/flutter/flutter/issues/98585
@Miedziaq you are free to remove new space characters from your string before passing them to Base64Decoder
. Dart implements Base64 decoder per RFC 4648 which is rather strict and requires rejecting incorrectly formatted strings. What you get from Outlook is MIME Base64 encoding which is slightly different (RFC 2045), it splits base64 data into lines (max 76 characters in a line) and thus introduces CRLF breaks. If you expect to decode MIME Base64 you can just sanitise your input to remove new lines before passing it to the decoder.
We could theoretically add an option to Base64Decoder
to accept MIME Base64 (by simply ignoring CRLF in the input). /cc @lrhn any opinion Lasse?
Base64 is really annoying to decode because you want to know the size of the decoded output first, so you can allocate a correctly sized Uint8List
.
That's possible by counting the number of input characters and parsing the trailing padding. (But not if streaming the input, then you just need to grow your buffer occasionally. It would really have been a much better format if it started with the output length, even if just written as decimal.)
Or it's possible if you know the size ahead-of-time because of metadata, which is at least possible for the MIME encodings.
If we allow \n
or \r\n
or other whitespace sequences inside the encoded text, then we either have to scan the entire input once to find the length, then do it again to decode, or we risk over-allocating and needing to return a view on the (unnecessarily) larger buffer.
So, I wouldn't want to allow whitespace by default. It could be something you opt in to, getting wither a slower set-up or a larger allocation (and a slower decoding in any case, since you have to check every character for being whitespace).
So possible, but not desirable as a generally enabled feature. I'd probably want to do a Base64Mime
codec for it, to keep the two decoders separate and individually tree-shakeable.
basically yes I can, but if I want to use some html viewer library and pass html to it, (like outlook email or some other) the base64 is only inside img tag, so this is not that easy to read the html file from internet and then remove spaces/newlines only from the img instances. since probably every technology has no problem with it, why this is that problem in flutter/dart...
for angular, for html, for c# its doesnt matter if you have this spaces/newlines or not
this technology aspire to be very useful and non-problematic, but it is more than others in this topic on example. There is mess, and non informative error messages like in lovely JAVA :>
Base64 is really annoying to decode because you want to know the size of the decoded output first, so you can allocate a correctly sized
Uint8List
. That's possible by counting the number of input characters and parsing the trailing padding. (But not if streaming the input, then you just need to grow your buffer occasionally. It would really have been a much better format if it started with the output length, even if just written as decimal.) Or it's possible if you know the size ahead-of-time because of metadata, which is at least possible for the MIME encodings.If we allow
\n
or\r\n
or other whitespace sequences inside the encoded text, then we either have to scan the entire input once to find the length, then do it again to decode, or we risk over-allocating and needing to return a view on the (unnecessarily) larger buffer.So, I wouldn't want to allow whitespace by default. It could be something you opt in to, getting wither a slower set-up or a larger allocation (and a slower decoding in any case, since you have to check every character for being whitespace).
So possible, but not desirable as a generally enabled feature. I'd probably want to do a
Base64Mime
codec for it, to keep the two decoders separate and individually tree-shakeable.
so, maybe it will be a good idea to provide overloaded methods for sync and async calls / or some switch to be more strict or less?
in basic use its not a really problem to remove this spaces/new lines, but in complicated cases, removing this spaces from the whole html file and generally editing it can be problematic time consuming and slower than just ignore this chars by decoder.
maybe I should request this feature to providers of html libraries on flutter? Im passing html file only there and i cannot control it completely.
https://pub.dev/packages/flutter_html
https://pub.dev/documentation/flutter_html_view/latest/
this works properly only in flutter webview
Im passing html file only there and i cannot control it completely.
It does sound like it is a bug in those packages. If they implement some specification like HTML which is support a different form of Base64 which is more lenient than RFC 4648 then they should not directly pass the data to the Base64Decoder
that Dart has.
The current version of dart-lang/sdk I'm using is the one used in flutter.
The decode function throwing an exception. It doesn't matter which Base64 decoder I use.
BASE64.decode() Base64Decode() BASE64URL.decode()
None of these functions work properly with larger images.
I've added the image in a pastebin that is generating the problem. https://pastebin.com/tDV4NfPV
The version of dart-lang/sdk is the version used by flutter. I've also tried importing the image using new Image.network. Nothing I do seems to fix this issue.
The exception it is throwing is as follows: