Sharing Images on the @platform in Flutter

Recently, I published a long article on how to read, write, and respond to real-time changes using the @platform. I focused mainly on sending plain old text and number data since that’s the easiest to demo with, but what if you wanted to let people share images? The good news is it’s possible!


To save on time and space, I’ll be building on top of the work I did in the last article. You can find the full at_protocol_basics repo here:

Send and Receive an Image

Pick an Image

You can use the image_picker package for image selection. 

class MediaService {
final picker = ImagePicker();
/// Select an image from the user's device
Future<File> selectImage({ImageSource source =}) async {
final pickedFile = await picker.getImage(source: source);
if(pickedFile!= null) {
return File(pickedFile.path);
} else {
return null;
view raw mediaService.dart hosted with ❤ by GitHub

Encode the Image

Once you have the file you need to encode it using the base2e15 package. As an FYI, this package is included in the dependencies for the at_client package so to use it, you just need to import it in your dart file.

import ‘package:base2e15/base2e15.dart’;

Base2e15 is a “binary-to-text encoding scheme that represents binary data in a unicode string format, each unicode character representing 15 bits of binary data”. What this means for us is that we can convert our image to a long list of text characters.

String encodedImage = Base2e15.encode(

Send the Image

Since the image is now in string form, we can send it on the @platform like we’d send any other string.

Future<void> sendImage() async {
AtKey atKey = AtKey();
atKey.key = 'pic';
/// Share with the other sign
if (shareWith) {
atKey.sharedWith = AtConstants().atMap[atProtocolService.currentAtSign];
String encodedImage = Base2e15.encode(
await atProtocolService.atClientImpl.put(atKey, encodedImage);
view raw at_send_image.dart hosted with ❤ by GitHub

Read and Decode the Image

You can read the encoded value using the get() method of your AtClient. The value that exists on your secondary server will look something like this thanks to the magic of Base2e15 encoding.

The decode method from the Base2e15 package returns a Uint8List.

Uint8List pic;
Future<void> readPic() async {
AtKey atKey = AtKey();
atKey.key = 'pic';
// Get keys shared by the other sign
if (!mine) {
atKey.sharedBy = AtConstants().atMap[atProtocolService.currentAtSign];
String serverValue = await atProtocolService.get(atKey);
print('Server value: ' + serverValue.toString());
if(serverValue != null){
pic = Base2e15.decode(serverValue);
view raw at_read_image.dart hosted with ❤ by GitHub

Display the Image

Displaying the image is the easiest part of the entire process.



Leave a Reply