dilate function
Performs a dilation operation on the input image.
This function takes a ui.Image and performs a dilation operation on it. The dilation operation expands the black pixels (letters) against the white background.
Parameters:
inputImage
: The source image to be dilated (black and white).kernelSize
: The size of the dilation kernel (must be an odd number).
Returns: A Future that resolves to a ui.Image containing the dilated image.
Implementation
Future<ui.Image> dilate({
required ui.Image inputImage,
required int kernelSize,
}) async {
final int width = inputImage.width;
final int height = inputImage.height;
// Get the pixel data from the input image
final ByteData? byteData =
await inputImage.toByteData(format: ui.ImageByteFormat.rawRgba);
if (byteData == null) {
throw Exception('Failed to get image data');
}
final Uint8List inputPixels = byteData.buffer.asUint8List();
// Create a new Uint8List for the output image
final Uint8List outputPixels = Uint8List(width * height * 4);
// Create the elliptical kernel
final List<List<bool>> kernel = _createEllipticalKernel(kernelSize);
// Apply dilation
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
bool hasBlackPixel = false;
for (int ky = 0; ky < kernelSize; ky++) {
for (int kx = 0; kx < kernelSize; kx++) {
if (kernel[ky][kx]) {
final int px = x + kx - kernelSize ~/ 2;
final int py = y + ky - kernelSize ~/ 2;
if (px >= 0 && px < width && py >= 0 && py < height) {
final int index = (py * width + px) * 4;
// Check if there's a black pixel in the kernel area
if (inputPixels[index] == 0) {
hasBlackPixel = true;
break;
}
}
}
}
if (hasBlackPixel) {
break;
}
}
final int outputIndex = (y * width + x) * 4;
final int pixelValue = hasBlackPixel ? 0 : 255;
outputPixels[outputIndex] = pixelValue; // R
outputPixels[outputIndex + 1] = pixelValue; // G
outputPixels[outputIndex + 2] = pixelValue; // B
outputPixels[outputIndex + 3] = 255; // Alpha channel
}
}
// Create a new ui.Image from the output pixels
final ui.ImmutableBuffer buffer =
await ui.ImmutableBuffer.fromUint8List(outputPixels);
final ui.ImageDescriptor descriptor = ui.ImageDescriptor.raw(
buffer,
width: width,
height: height,
pixelFormat: ui.PixelFormat.rgba8888,
);
final ui.Codec codec = await descriptor.instantiateCodec();
final ui.FrameInfo frameInfo = await codec.getNextFrame();
return frameInfo.image;
}