binarize

Last updated:

0 purchases

binarize Image
binarize Images
Add to Cart

Description:

binarize

Binarize #





From Wiktionary:

Etymology #
binary + size
Verb #
binarize (third-person singular simple present binarizes, present participle
binarizing, simple past and past participle binarized)

(mathematics) To represent in binary (base 2) notation
To convert (an image) to only black and white.
(statistics) To dichotomize a variable.


Binarize is a package that wraps the ByteData functionality into a more streamlined and
extendable payload system.
With Binarize you can easily create and read binary data into the correct value types without
having to check for the correct byte offset or figure out which ByteData method you need to use.
This is especially useful for when you are implementing a file format specification, like the
PSD File Format.
Installation #
Add binarize as a dependency to your pubspec.yaml file (what?).
Import Binarize:
import 'package:binarize/binarize.dart';
copied to clipboard
Docs & API #
The API Docs
provide information about how to use Binarize.
If you want to see Binarize in practice, check the example.
It showcases all the types that Binarize provides.
Usage #
Writing #
The Payload.write method returns a PayloadWriter that is used for writing values using
different PayloadTypes:
import 'package:binarize/binarize.dart';

void main() {
final writer = Payload.write()
..set(uint8, 16);
..set(string32, 'Hello World');
}
copied to clipboard
The binarize method accepts a PayloadWriter and converts the values to binary:
void main() {
final writer = Payload.write();

...

// Binarize the writer to a Uint8List.
final bytes = binarize(writer);

...
}
copied to clipboard
Reading #
The Payload.read method returns a PayloadReader that reads a list of bytes. The data from that
list can be retrieved by using different PayloadTypes:
import 'package:binarize/binarize.dart';

void main() {
...

final reader = Payload.read(bytes);

final aUint8 = reader.get(uint8);
final aString = reader.get(string32);

...
}
copied to clipboard
Note: The order in which the values are written is also the order in which they have to be
retrieved.
PayloadTypes #
PayloadTypes are the backbone of Binarize, they do all the heavy lifting of packing and unpacking
bytes. Binarize provides all the basis types that the ByteData class has to offer. But in some
cases a developer might want to create their own PayloadType. Thankfully Binarize's API allows
for defining custom PayloadTypes.
Here is an example for a PayloadType that packs and unpacks the Vector2 class from the
vector_math library:
import 'package:binarize/binarize.dart';
import 'package:vector_math/vector_math.dart';

// Define the PayloadType class, it is private as we only want to have a
// single constant instance for it.
class _Vector2 extends PayloadType<Vector2> {
const _Vector2();

// The byte length, it should return the total byte length it will use for a
// given value. In this case we have two float32 values, each uses 4 bytes
// so our total length is 8.
@override
int length(Vector2 value) => 8;

// Called when the user reads data, the offset is the current read offset
// in the given data.
@override
Vector2 get(ByteData data, int offset) {
return Vector2(
// Read the x value at the current offset.
data.getFloat32(offset),
// Read the y value at the current offset + 4. Float32 has a default
// byte length of 4 so we have to take that into consideration so
// that we don't read the x value again.
data.getFloat32(offset + 4),
);
}

// Called when the user write data, the offset is the current write offset
// in the given byte data.
@override
void set(Vector2 value, ByteData data, int offset) {
// Write the x value at the current offset.
data.setFloat32(offset, value.x);
// Write the y value at the current offset + 4. The 4 is needed as Float32
// have a byte length of 4 so we have to take that into consideration so
// we don't overwrite the x value.
data.setFloat32(offset + 4, value.y);
}
}

// And finally the user-facing variable that users can use to read and write
// with.
const vector2 = _Vector2();
copied to clipboard
The vector2 can be used like any other PayloadType:
import 'package:binarize/binarize.dart';
import 'package:vector_math/vector_math.dart';

// Import the newly created vector2 PayloadType.
import './types/vector2.dart';

void main() {
// Write a Vector2.
final writer = Payload.write()..set(vector2, Vector2(100.5, 200));

// Binarize the writer to a Uint8List.
final bytes = binarize(writer);

// Reading the bytes.
final reader = Payload.read(bytes);

// The x value will be 100.5 and the y value will be 200.
final aVector2 = reader.get(vector2);
}
copied to clipboard
BinaryContract #
The BinaryContract allows developers to define a strongly typed binary
representation of a Dart class. If your Dart class contract changes, so will
the binary contract, ensuring you never forget to change how the data is being
read or stored.
BinaryContract works best with classes that are immutable, because it will
implement your class by overwriting the fields as getters. If your fields
are not final Dart will complain that the setter was not implement. There
are ways to work around this but it is not recommended.
An example of how you can implement a BinaryContract for your own classes:
class MyClass {
const MyClass({
required this.myProperty,
});

final int myProperty;
}

/// Defining the contract for the [MyClass] class. It should also implement the
/// class so the contract can access the fields.
class _MyClassContract extends BinaryContract<MyClass> implements MyClass {
/// Pass a base line instance to the super constructor. This is used to build
/// up the, contact, the values defined in the base line do not matter.
const _MyClassContract()
: super(const MyClass(myProperty: 1337));

/// This method allows the [BinaryContract] to know the order of how the binary
/// data should be read and stored.
///
/// [contract] is always the [BinaryContract] instance.
@override
MyClass order(MyClass contract) {
return MyClass(
myProperty: contract.myProperty,
);
}

/// The properties of the [MyClass] need to be implemented as getters.
@override
int get myProperty => type(uint16, (o) => o.myProperty);
}

// Create a constant instance of the contract.
const myClassContract = _MyClassContract();

void main() {
// Create a new instance of MyClass.
final myClass = MyClass(myProperty: 1337);

// Store the instance using the contract.
final writer = Payload.write()..set(myClassContract, myClass);
final bytes = binarize(writer);

// Read it back from binary.
final reader = Payload.read(bytes);
final myClassAgain = reader.get(myClassContract);

print(myClassAgain.myProperty); // Returns 1337
}
copied to clipboard
The BinaryContract extends from PayloadType and can be used within other payloads, including
itself.

License:

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.