A protocol implementation for bidirectional transformation between binary masks and Run-Length Encoding (RLE), enabling efficient transmission of binary mask data across various services.
This project provides a standardized protocol for converting binary masks to RLE format, allowing for significantly smaller data transmission volumes while maintaining full data integrity. The protocol is designed to be language-agnostic, fast, lossless, and JSON-compatible.
- Multi-language support with Python (pyrle) and TypeScript/JavaScript (tsrle) implementations
- JSON-compatible format for seamless API integration without file uploads
- Fast performance with optimized algorithms and automatic mode selection
- Lossless compression with 100% data integrity guarantee
- Minimal size with 70-95% typical compression ratios
import numpy as np
from pyrle import encode, decode
# Create a binary mask
mask = np.zeros((100, 100), dtype=np.uint8)
mask[40:60, 40:60] = 1 # Rectangle in the center
# Encode to RLE (auto-detects optimal mode)
encoded = encode(mask)
print(f"Original size: {mask.nbytes} bytes")
print(f"Encoded size: {len(encoded) * 4} bytes") # 4 bytes per uint32
print(f"Compression ratio: {mask.nbytes / (len(encoded) * 4):.1f}x")
# Decode back to mask
decoded = decode(encoded)
assert np.array_equal(mask, decoded)
# Force specific encoding mode
encoded_v0 = encode(mask, mode=0) # Simple mode
encoded_v1 = encode(mask, mode=1) # Complex modeimport { encode, decode } from '@meshy/tsrle';
// Create a binary mask
const rows = 100;
const cols = 100;
const mask = new Uint8Array(rows * cols);
// Set foreground pixels (example: rectangle in center)
for (let i = 40; i < 60; i++) {
for (let j = 40; j < 60; j++) {
mask[i * cols + j] = 1;
}
}
// Encode to RLE
const encoded = encode(mask, rows, cols);
console.log(`Original size: ${mask.length} bytes`);
console.log(`Encoded size: ${encoded.length * 4} bytes`);
console.log(`Compression ratio: ${mask.length / (encoded.length * 4)}x`);
// Decode back to mask
const { mask: decoded, rows: decodedRows, cols: decodedCols } = decode(encoded);
console.log('Decoded successfully:', decodedRows === rows && decodedCols === cols);
// Use with JSON
const jsonPayload = {
imageId: 'example-123',
mask: Array.from(encoded), // Convert to regular array for JSON
timestamp: Date.now()
};// Frontend: Send mask data in JSON
const mask = createBinaryMask(); // Your mask creation logic
const encoded = encode(mask, rows, cols);
const response = await fetch('/api/process-mask', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
mask: Array.from(encoded),
metadata: { rows, cols }
})
});
// Backend: Process received mask
const { mask: encodedMask, metadata } = await request.json();
const { mask: decodedMask } = decode(new Uint32Array(encodedMask));
// Process the binary mask...Copyright (c) Meshy LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
