adjustDocumentCorners method
Implementation
@override
Future<String?> adjustDocumentCorners(String base64Image) {
final completer = Completer<String?>();
final html.DivElement modal = html.DivElement()
..style.position = 'fixed'
..style.left = '0'
..style.top = '0'
..style.width = '100%'
..style.height = '100%'
..style.backgroundColor = 'rgba(0, 0, 0, 0.8)'
..style.zIndex = '9999'
..style.display = 'flex'
..style.flexDirection = 'column'
..style.alignItems = 'center'
..style.justifyContent = 'center';
final html.CanvasElement canvas = html.CanvasElement()
..style.borderRadius = '10px';
final context = canvas.getContext('2d') as html.CanvasRenderingContext2D;
final html.ImageElement imageElement = html.ImageElement()
..src = 'data:image/jpeg;base64,$base64Image';
void drawCornersAndLines(
html.CanvasRenderingContext2D ctx, List<Map<String, int>> corners) {
ctx.clearRect(0, 0, canvas.width!, canvas.height!);
ctx.drawImage(imageElement, 0, 0);
// ctx.clearRect(
// corners[0]['x']!,
// corners[0]['y']!,
// corners[1]['x']! - corners[0]['x']!,
// corners[1]['y']! - corners[0]['y']!);
// Maybe there is a better way to do it..
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.fillRect(0, 0, corners[1]['x']!, corners[0]['y']!);
ctx.fillRect(corners[1]['x']!, 0, canvas.width! - corners[1]['x']!,
canvas.height!);
ctx.fillRect(
0,
corners[1]['y']!,
canvas.width! - (canvas.width! - corners[1]['x']!),
canvas.height! - corners[1]['y']!);
ctx.fillRect(
0,
corners[0]['y']!,
corners[0]['x']!,
canvas.height! -
corners[0]['y']! -
(canvas.height! - corners[1]['y']!));
ctx.strokeStyle = 'gray';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(corners[0]['x']!, corners[0]['y']!);
ctx.lineTo(corners[0]['x']!, corners[1]['y']!);
ctx.lineTo(corners[1]['x']!, corners[1]['y']!);
ctx.lineTo(corners[1]['x']!, corners[0]['y']!);
ctx.lineTo(corners[0]['x']!, corners[0]['y']!);
ctx.stroke();
for (final corner in corners) {
ctx.fillStyle = 'white';
ctx.fillRect(corner['x']! - 5, corner['y']! - 5, 10, 10);
}
}
var corners = [
{'x': 50, 'y': 50},
{'x': canvas.width! - 50, 'y': canvas.height! - 50},
];
imageElement.onLoad.listen((event) {
canvas.width = imageElement.width ?? 800;
canvas.height = imageElement.height ?? 600;
corners = [
{'x': 50, 'y': 50},
{'x': canvas.width! - 50, 'y': canvas.height! - 50},
];
context.drawImage(imageElement, 0, 0);
drawCornersAndLines(context, corners);
});
canvas.onMouseDown.listen((event) {
final rect = canvas.getBoundingClientRect();
final mouseX = event.client.x - rect.left;
final mouseY = event.client.y - rect.top;
int? selectedCornerIndex;
for (int i = 0; i < corners.length; i++) {
final corner = corners[i];
final dx = mouseX - corner['x']!;
final dy = mouseY - corner['y']!;
if (dx * dx + dy * dy <= 25) {
// 25 is 5*5 where 5 is the half side length of the corner square
selectedCornerIndex = i;
break;
}
}
if (selectedCornerIndex != null) {
onMouseMove(html.MouseEvent moveEvent) {
final newMouseX = moveEvent.client.x - rect.left;
final newMouseY = moveEvent.client.y - rect.top;
corners[selectedCornerIndex!]['x'] = newMouseX.toInt();
corners[selectedCornerIndex]['y'] = newMouseY.toInt();
drawCornersAndLines(context, corners);
}
final moveSubscription = html.document.onMouseMove.listen(onMouseMove);
onMouseUp(html.MouseEvent upEvent) {
moveSubscription.cancel();
}
html.document.onMouseUp.listen(onMouseUp);
}
});
final html.ButtonElement saveButton = html.ButtonElement()
..innerText = 'Save'
..style.marginTop = '20px'
..style.padding = '10px 20px'
..style.fontSize = '16px'
..style.borderRadius = '5px'
..onClick.listen((_) {
final html.CanvasElement canvas = html.CanvasElement();
final width = corners[1]['x']! - corners[0]['x']!;
final height = corners[1]['y']! - corners[0]['y']!;
canvas.width = width;
canvas.height = height;
final html.CanvasRenderingContext2D context =
canvas.getContext('2d') as html.CanvasRenderingContext2D;
// Now I plot the image bounded by corners to canvas
context.drawImageScaledFromSource(imageElement, corners[0]['x']!,
corners[0]['y']!, width, height, 0, 0, width, height);
final base64Image = canvas.toDataUrl().split(',').last;
modal.remove();
// Process and save the adjusted image if necessary
completer.complete(
base64Image); // Replace with actual adjusted image data if needed
});
final html.ButtonElement cancelButton = html.ButtonElement()
..innerText = 'Cancel'
..style.marginTop = '10px'
..style.padding = '10px 20px'
..style.fontSize = '16px'
..style.borderRadius = '5px'
..onClick.listen((_) {
modal.remove();
completer.complete(null);
});
modal.append(canvas);
modal.append(saveButton);
modal.append(cancelButton);
html.document.body?.append(modal);
return completer.future;
}