4

I got image Base64 encoded image data, but one of the images I got was not uploaded and gives an error in the form of

invalid length must be multiple of four.

Also, my other images appear for a moment and then disappear for a moment. They come and go. Is there a solution for this issue?

     Widget image(String thumbnail) {
        final _byteImage = Base64Decoder().convert(thumbnail);
        Widget image = Image.memory(_byteImage);
        return image;
      }

 child: Column(
                    children: [
                      image(item.thumbnail),
                      Text(
                        item.name,
                        style: TextStyle(fontSize: 14, fontWeight: FontWeight.normal,fontFamily: 'Poppins'),
                        maxLines: 2,
                      ),
                    ],
                  ),
kimSoo
  • 283
  • 1
  • 4
  • 10

2 Answers2

4

You need to pad the Base64 string with one or two "=" to reach a length that is a multiple of 4.

If it can be divided by 4 without rest, it's fine. If the remainder of length modulo 4 is 3, you add 1 '=' and if the remainder is '2 you add 2 '=' to the string.

In dart you get the length of a string with "".length and then calculate the remainder of a division by 4 with the modulo operator %:

As the actual problem turned out to be a null string, the following code also checks for null or empty strings and shows a placeholder image instead of an error message.

Widget image(String thumbnail) {
        String placeholder = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
        if (thumbnail?.isEmpty ?? true)
            thumbnail = placeholder;
        else {
            if (thumbnail.length % 4 > 0) { 
                thumbnail += '=' * (4 - thumbnail .length % 4) // as suggested by Albert221
            }
        }
        final _byteImage = Base64Decoder().convert(thumbnail);
        Widget image = Image.memory(_byteImage);
        return image;
      }
jps
  • 20,041
  • 15
  • 75
  • 79
  • @kimSoo: can you please be more specific what exactly didn't work? Of course I also tried it and when I removed the padding from a test image, it first failed, but when I padded with the above code, it worked fine, the image was displayed. The error mentioned in your question should be gone. – jps Sep 17 '20 at 19:44
  • Sorry, I tried the code directly, but I still get the same error. Although my other images are loaded normally but this is not loading – kimSoo Sep 17 '20 at 19:49
  • there is an error on the console---Invalid length, must be multiple of four (at character 10) not-found – kimSoo Sep 17 '20 at 19:50
  • I think I understood the reason. It doesn't send any picture for this value, so it's a null value. – kimSoo Sep 17 '20 at 20:35
  • I think It gives an error because of this. is it possible? – kimSoo Sep 17 '20 at 20:36
  • @kimSoo : I added an improvement to check for null or emtpy values and show a placeholder to avoid error messages. – jps Sep 18 '20 at 08:15
  • will cropping the image reduces the length of the string? – 钟智强 Apr 05 '21 at 04:21
  • BTW I did it this way: `payloadPart += '=' * (4 - payloadPart.length % 4)`. That's much shorter. – Albert221 Apr 12 '21 at 08:31
  • @Albert221 thanks, I updated my answer with your improvement – jps Apr 12 '21 at 14:00
  • There is also `String fixed = base64.normalize(str)` which does pretty much the same thing. (But you need to `import 'dart:convert';` ) – ippi Jun 23 '21 at 04:22
4

First you need to import

import 'dart:convert';

So normalize the base64 String

Base64Codec base64 = const Base64Codec();

base64.normalize(thumbnail)
Community
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 17 '22 at 12:46