Using Dart to turn a PNG file into a binary text file image.

I recently saw an interesting bit of Python code by Rohit Midha where he created a binary text image from a PNG. Given that I'm busy learning to use Dart as a more generic programming language, instead of just for mobile work, I was curious how I'd do this.

The idea is to take an image, like this:

And turn it into a text file, like this:

        
        0000000000000000000000000000000000000000000111111111111111000000000000000000000000000000000000000000
        0000000000000000000000000000000000000111111111111111111111111110000000000000000000000000000000000000
        0000000000000000000000000000000000111111111111111111111111111111111000000000000000000000000000000000
        0000000000000000000000000000000111111111111111111111111111111111111110000000000000000000000000000000
        0000000000000000000000000000011111111111111111111111111111111111111111110000000000000000000000000000
        0000000000000000000000000001111111111111111111111111111111111111111111111100000000000000000000000000
        0000000000000000000000001111111111111111111111111111111111111111111111111111000000000000000000000000
        0000000000000000000000011111111111111111111111111111111111111111111111111111110000000000000000000000
        0000000000000000000001111111111111111111111111111111111111111111111111111111111000000000000000000000
        0000000000000000000011111111111111111111111111111111111111111111111111111111111110000000000000000000
        0000000000000000001111111111111111111111111111111111111111111111111111111111111111000000000000000000
        0000000000000000011111111111111111111111111111111111111111111111111111111111111111100000000000000000
        0000000000000000111111111111111111111111111111111111111111111111111111111111111111110000000000000000
        0000000000000000111111111111111111111111111111111111111111111111111111111111111111111000000000000000
        0000000000000011111111111111111111111111111111111111111111111111111111111111111111111100000000000000
        0000000000000011111111111111111111111111111111111111111111111111111111111111111111111110000000000000
        0000000000001111111111111111111111111111111111111111111111111111111111111111111111111111000000000000
        0000000000011111111111111111111111111111111111111111111111111111111111111111111111111111100000000000
        0000000000111111111111111111111111111111111111100000011111111111111111111111111111111111110000000000
        0000000000111111111111111111111111111111110000000000000000011111111111111111111111111111111000000000
        0000000001111111111111111111111111111110000000000000000000000011111111111111111111111111111100000000
        0000000011111111111111111111111111110000000000000000000000000011111111111111111111111111111100000000
        0000000111111111111111111111111111000000000000000000000000000111111111111111111111111111111110000000
        0000000111111111111111111111111110000000000000000000000000001111111111111111111111111111111111000000
        0000001111111111111111111111111000000000000000000000000000001111111111111111111111111111111111000000
        0000001111111111111111111111110000000000000000000000000000011111111111111111111111111111111111000000
        0000001111111111111111111111110000000000000000000000000000111111111111111111111111111111111111100000
        0000011111111111111111111111100000000000000000000000000001111111111111111111111111111111111111100000
        0000011111111111111111111111000000000000000000000000000011111111111111111111111111111111111111110000
        0000111111111111111111111110000000000000000000000000000111111111111111111111111111111111111111110000
        0000111111111111111111111000000000000000000000000000001111111111111111111111111111111111111111111000
        0001111111111111111111111000000000000000000000000000011111111111111111111111111111111111111111111000
        0001111111111111111111110000000000000000000000000000111111111111111111111111111111111111111111111100
        0001111111111111111111100000000000000000000000000001111111111111111111111111111111111111111111111100
        0011111111111111111111100000000000000000000000000111111111111111111111111111111111111111111111111100
        0011111111111111111111000000000000000000000000001111111111111111111111111111111111111111111111111110
        0011111111111111111110000000000000000000000000011111111111111111111111111111110111111111111111111110
        0111111111111111111110000000000000000000000000111111111111111111111111111111100011111111111111111110
        0111111111111111111110000000000000000000000000111111111111111111111111111111000011111111111111111110
        0111111111111111111100000000000000000000000001111111111111111111111111111110000011111111111111111110
        0111111111111111111100000000000000000000000011111111111111111111111111111100000001111111111111111111
        0111111111111111111100000000000000000000000111111111111111111111111111111000000001111111111111111111
        1111111111111111111000000000000000000000001111111111111111111111111111110000000001111111111111111111
        1111111111111111111000000000000000000000011111111111111111111111111111100000000001111111111111111111
        1111111111111111111000000000000000000001111111111111111111111111111111000000000000111111111111111111
        1111111111111111111000000000000000000011111111111111111111111111111110000000000000111111111111111111
        1111111111111111111000000000000000000111111111111111111111111111111100000000000000111111111111111111
        1111111111111111110000000000000000001111111111111111111111111111111000000000000000111111111111111111
        1111111111111111110000000000000000011111111111111111111111111111110000000000000000111111111111111111
        1111111111111111110000000000000000111111111111111111111111111111100000000000000000111111111111111111
        1111111111111111110000000000000000111111111111111111111111111111000000000000000000111111111111111111
        1111111111111111110000000000000001111111111111111111111111111110000000000000000000111111111111111111
        1111111111111111110000000000000011111111111111111111111111111100000000000000000000111111111111111111
        1111111111111111110000000000000111111111111111111111111111111000000000000000000000111111111111111111
        1111111111111111111000000000001111111111111111111111111111110000000000000000000000111111111111111111
        1111111111111111111000000000011111111111111111111111111111100000000000000000000000111111111111111111
        1111111111111111111000000000111111111111111111111111111111000000000000000000000000111111111111111111
        1111111111111111111000000001111111111111111111111111111110000000000000000000000001111111111111111111
        0111111111111111111000000111111111111111111111111111111100000000000000000000000001111111111111111111
        0111111111111111111100001111111111111111111111111111111000000000000000000000000001111111111111111111
        0111111111111111111100011111111111111111111111111111110000000000000000000000000011111111111111111111
        0111111111111111111110111111111111111111111111111111100000000000000000000000000011111111111111111110
        0111111111111111111111111111111111111111111111111111000000000000000000000000000011111111111111111110
        0011111111111111111111111111111111111111111111111110000000000000000000000000000111111111111111111110
        0011111111111111111111111111111111111111111111111000000000000000000000000000000111111111111111111110
        0011111111111111111111111111111111111111111111110000000000000000000000000000001111111111111111111100
        0011111111111111111111111111111111111111111111100000000000000000000000000000001111111111111111111100
        0001111111111111111111111111111111111111111111000000000000000000000000000000011111111111111111111100
        0001111111111111111111111111111111111111111110000000000000000000000000000000111111111111111111111000
        0000111111111111111111111111111111111111111100000000000000000000000000000000111111111111111111111000
        0000111111111111111111111111111111111111111000000000000000000000000000000011111111111111111111111000
        0000111111111111111111111111111111111111110000000000000000000000000000000111111111111111111111110000
        0000011111111111111111111111111111111111100000000000000000000000000000001111111111111111111111110000
        0000011111111111111111111111111111111111000000000000000000000000000000011111111111111111111111100000
        0000001111111111111111111111111111111110000000000000000000000000000000111111111111111111111111100000
        0000001111111111111111111111111111111100000000000000000000000000000000111111111111111111111111000000
        0000000111111111111111111111111111111000000000000000000000000000000001111111111111111111111111000000
        0000000111111111111111111111111111111000000000000000000000000000000111111111111111111111111110000000
        0000000011111111111111111111111111100000000000000000000000000000011111111111111111111111111110000000
        0000000011111111111111111111111111111000000000000000000000000001111111111111111111111111111100000000
        0000000001111111111111111111111111111111000000000000000000001111111111111111111111111111111000000000
        0000000000111111111111111111111111111111111100000000000001111111111111111111111111111111111000000000
        0000000000011111111111111111111111111111111111111111111111111111111111111111111111111111110000000000
        0000000000001111111111111111111111111111111111111111111111111111111111111111111111111111100000000000
        0000000000000111111111111111111111111111111111111111111111111111111111111111111111111110000000000000
        0000000000000011111111111111111111111111111111111111111111111111111111111111111111111100000000000000
        0000000000000001111111111111111111111111111111111111111111111111111111111111111111111100000000000000
        0000000000000000111111111111111111111111111111111111111111111111111111111111111111110000000000000000
        0000000000000000011111111111111111111111111111111111111111111111111111111111111111110000000000000000
        0000000000000000001111111111111111111111111111111111111111111111111111111111111111100000000000000000
        0000000000000000000111111111111111111111111111111111111111111111111111111111111110000000000000000000
        0000000000000000000011111111111111111111111111111111111111111111111111111111111100000000000000000000
        0000000000000000000000111111111111111111111111111111111111111111111111111111111000000000000000000000
        0000000000000000000000001111111111111111111111111111111111111111111111111111100000000000000000000000
        0000000000000000000000000011111111111111111111111111111111111111111111111110000000000000000000000000
        0000000000000000000000000000111111111111111111111111111111111111111111111000000000000000000000000000
        0000000000000000000000000000001111111111111111111111111111111111111111100000000000000000000000000000
        0000000000000000000000000000000011111111111111111111111111111111111100000000000000000000000000000000
        0000000000000000000000000000000000011111111111111111111111111111100000000000000000000000000000000000
        0000000000000000000000000000000000000000111111111111111111111000000000000000000000000000000000000000
        
        

To start with, you need a way to open image files in Dart. Fortunately, there is a great package for that already, which we can just add to our pubspec.yaml file. Because we'll be working with file IO, we will need to make the main method async, as this will allow us to wait for async operations to complete. In this case, it'll be to ensure we've written all data to files before we close them.

To make things easier for ourselves, we will be resizing the image to a smaller width, preserving the aspect ratio. In this case, we specify the width as 100, which means that out output file will have strings of 100 characters long to present the image with. If we didn't do this, we'd end up with gigantic text files!

Using the Image package, we load the source file, turn it into a grayscale image and get the bytes representing the image as an array. Note that PNG's use 4 bytes per pixel (bpp) to represet Red, Green, Blue and Alpha channels. We loop through the array, writing a 1 to the text file whenever a pixel value is set, or 0 when it's not. We also write a newline to the file every time we hit a multiple of the image width.

Finally, we flush the sink stream and close it, ensuring our data is written to disk. This is where the await keyword makes life easier. You simply specify await and the async operation you want to wait for, before execution will continue. This is so much easier than trying to manage threads yourself.

There you have it - a simple and easy way to create binary text file images from PNGs. Dart is a versatile language that can be used for much more than just writing Flutter applications. I'll be exploring other ways of using Dart as a server-side development language in other programming posts.


Source Code:
            
/**
* Converts an input image to a text file using 1's and 0's.
* Done as a learning experiment in Dart.
*/

import 'dart:io';
import 'package:image/image.dart';

void main() async {
  const width = 100;
  const bpp = 4;
  String inputFile = "sourcefile.png";
  String outputFilename = "result.txt";

  var pixels = grayscale(copyResize(decodeImage(new File(inputFile).readAsBytesSync()), width)).getBytes();
  var sink = File(outputFilename).openWrite();

  for (var i = 0; i < pixels.length; i += bpp) {
    if ((i / bpp) % width == 0) {
      sink.write("\n");
    }

    sink.write((pixels[i] + pixels[i + 1] + pixels[i + 2] > 0) ? '1' : '0');
  }

  await sink.flush();
  await sink.close();
}

Share

Share via Twitter

Resources

Dart Image Package
Binarify in Python by Rohit Midha

Return to the NoFuss Solutions website.