-
-
Notifications
You must be signed in to change notification settings - Fork 505
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crop on web improvement #407
Comments
Keep in mind this is not fully tested and may contain some bugs. |
I'm not the author, but happy for any improvements. See related code: #394 Importantly, your decode logic can be simplified (and made generic) while keeping speed improvements |
@FRANIAZA what this function return ? :- getBlobData(await myCanvas.toBlob(mimeType ?? 'image/jpeg')) |
Right, sorry. Future<Uint8List> getBlobData(html.Blob blob) {
final completer = Completer<Uint8List>();
final reader = html.FileReader();
reader.readAsArrayBuffer(blob);
reader.onLoad.listen((_) => completer.complete(reader.result as Uint8List));
return completer.future;
} |
yeah Thanks! @FRANIAZA |
Actually, this doesn't work on Web
Right? |
I believe it does. What doesn't work on Web are file paths, maybe you're referring to that? |
I am not. I'm using exactly the same code you wrote and running on the web... Has an issue with using
|
I tested it just now and it works fine. I am using extended_image: ^5.1.2 and Flutter 2.5.3. |
Tested with flutter 2.8.1 and extended_image: ^6.0.1 -> still works |
If you would like I could send you the dart file of my cropping page via email to provide a complete usage example |
guys, is it me, or when we crop it becomes smaller and with smaller image quality, for the flutter candies way @SeriousMonk |
Of course. That's how cropping works. |
but I cropped a 600 dpi image to a 500 * 500 pixels square. But when i get the data and save it I get my same image as a 382 *382 pixels and 96 dpi. |
That seems like a problem with your integration of the image cropper. This function simply takes the data from the |
yes crop rect,size keeps on changing |
@SeriousMonk thank you, I updated the code to import 'dart:async';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:ui';
import 'package:cross_file/cross_file.dart';
import 'package:extended_image/extended_image.dart';
import 'package:image/image.dart' as img;
class ImageExport {
const ImageExport();
Future<html.ImageElement> createHtmlImageElement(String path) {
final completer = Completer<html.ImageElement>();
final imageElement = html.ImageElement();
imageElement.onError.first.then((value) {
completer.completeError(Exception('Could not load Image'));
});
imageElement.onLoad.first.then((value) {
completer.complete(imageElement);
});
imageElement.src = path;
return completer.future;
}
Future<Uint8List> export({
required EditActionDetails editAction,
required Rect cropRect,
required Uint8List source,
int quality = 100,
}) async {
final imageElement = await createHtmlImageElement(XFile.fromData(source).path);
html.CanvasElement canvas;
/// If cropping is needed create a canvas of the size of the cropped image
/// else create a canvas of the size of the original image
if (editAction.needCrop) {
canvas = html.CanvasElement(width: cropRect.width.toInt(), height: cropRect.height.toInt());
} else {
canvas = html.CanvasElement(width: imageElement.width, height: imageElement.height);
}
final ctx = canvas.context2D;
var drawWidth = canvas.width!;
var drawHeight = canvas.height!;
/// This invert flag will be true if the image has been rotated 90 or 270 degrees
/// if that happens draWidth and drawHeight will have to be inverted
/// and Flip.vertical and Flip.horizontal will have to be swapped
var invert = false;
if (editAction.hasRotateAngle) {
if (editAction.rotateAngle == 90 || editAction.rotateAngle == 270) {
final tmp = canvas.width!;
canvas
..width = canvas.height
..height = tmp;
drawWidth = canvas.height!;
drawHeight = canvas.width!;
invert = true;
}
ctx
..translate(canvas.width! / 2, canvas.height! / 2)
..rotate(editAction.rotateAngle * math.pi / 180);
} else {
ctx.translate(canvas.width! / 2, canvas.height! / 2);
}
/// By default extended_image associates
/// editAction.flipY == true => img.FlipDirection.horizontal and
/// editAction.flipX == true => img.FlipDirection.vertical
if (editAction.needFlip) {
late img.FlipDirection mode;
if (editAction.flipY && editAction.flipX) {
mode = img.FlipDirection.both;
} else if (editAction.flipY) {
if (invert) {
mode = img.FlipDirection.vertical;
} else {
mode = img.FlipDirection.horizontal;
}
} else if (editAction.flipX) {
if (invert) {
mode = img.FlipDirection.horizontal;
} else {
mode = img.FlipDirection.vertical;
}
}
/// ctx.scale() multiplicates its values to the drawWidth and drawHeight
/// in ctx.drawImageScaledFromSource
/// so applying ctx.scale(-1, 1) is like saying -drawWidth which means
/// flip horizontal
switch (mode) {
case img.FlipDirection.horizontal:
if (invert) {
ctx.scale(1, -1);
} else {
ctx.scale(-1, 1);
}
break;
case img.FlipDirection.vertical:
if (invert) {
ctx.scale(-1, 1);
} else {
ctx.scale(1, -1);
}
break;
case img.FlipDirection.both:
ctx.scale(-1, -1);
break;
}
}
ctx.drawImageScaledFromSource(
imageElement,
cropRect.left,
cropRect.top,
cropRect.width,
cropRect.height,
-drawWidth / 2,
-drawHeight / 2,
drawWidth,
drawHeight,
);
final blob = await canvas.toBlob('image/jpeg', quality / 100);
final path = html.Url.createObjectUrlFromBlob(blob);
return XFile(path, mimeType: blob.type).readAsBytes();
}
} |
https://pub.dev/packages/extended_image/versions/9.0.3 extended_image support free angle rotation now, If anyone has time to support it, please provide a PR. thank you. |
Using the image library on web to apply the transformations is slow and freezes the UI.
Using the following method instead of "cropImageDataWithDartLibrary" takes significantly less time and doesn't freeze the UI:
The text was updated successfully, but these errors were encountered: