How to split an image into equal-sized parts? Just taking an image from asset and splitting it into equal parts in a grid-like manner, so that each image part can be used as a separate image.
How to split/divide image in parts in Flutter
Asked Answered
You can use this package (https://pub.dev/packages/image) to crop the image from asset with the function copyCrop. Save them to List then display like your example.
Edit:
I think you know how to split your image and display them like your example if you know how to crop your image so I just show you how to change from image from asset to image of image package for cropping.
List<Image> splitImage(List<int> input) {
// convert image to image from image package
imglib.Image image = imglib.decodeImage(input);
int x = 0, y = 0;
int width = (image.width / 3).floor();
int height = (image.height / 3).floor();
// split image to parts
List<imglib.Image> parts = List<imglib.Image>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
parts.add(imglib.copyCrop(image, x, y, width, height));
x += width;
}
x = 0;
y += height;
}
// convert image from image package to Image Widget to display
List<Image> output = List<Image>();
for (var img in parts) {
output.add(Image.memory(imglib.encodeJpg(img)));
}
return output;
}
Remember to add this import 'package:image/image.dart' as imglib;
could you give an example code or link an example post for the grid-like split? –
Broadfaced
the output return in function is Image Widget, so you can add it into Container child to display these image –
Cohe
just figured that out; thanks for the code; could you edit the code to correct the minor issue and then I can mark it as accepted. –
Broadfaced
Is there a way to check if 2 images are equal or similar to each other? need help with stackoverflow.com/questions/58372045 –
Broadfaced
Can I split the image into arbitrary shapes rather than just a rectangle? Like using a
Path
to define the shape of the cut. –
Broadfaced I didn't try it yet but let try copyRectify() function in image package –
Cohe
pub.dev/documentation/image/latest/image/copyRectify.html let me cut a 4-sided polygon rather than a general shape like this one images.vexels.com/media/users/3/167408/isolated/lists/… –
Broadfaced
If you just want to display it to screen and do nothing with it, you can use ClipPath widget –
Cohe
no, I want it as a
Draggable
. And then it can be dropped to a DragTarget
. My current implementation of the ClipPath widget draws the required shape but also draws the extra part without painting it. –
Broadfaced I have simplified my question here stackoverflow.com/questions/58554601 –
Broadfaced
It's probably better to use
floor()
for rounding integers instead of using round()
when calculating cell width & height. Otherwise it could lead to RangeError (index): Index out of range
because all the extra fractions could add up and when trying to slice the last one with the width/height that goes beyond image boundary and cause this. floor is just the safest option in that case. –
Buskined Modified hoangquyy's answer a bit, so you can just pass the asset path to the function and get a list of images:
import 'package:image/image.dart' as imglib;
Future<List<Image>> splitImage(String path) async {
imglib.Image? image = await decodeAsset(path);
List<Image> pieces = [];
int x = 0, y = 0;
int width = (image!.width / 3).floor();
int height = (image.height / 3).floor();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
imglib.Image croppedImage = imglib.copyCrop(image, x: x, y: y, width: width, height: height);
pieces.add(Image.memory(imglib.encodeJpg(croppedImage)));
x += width;
}
x = 0;
y += height;
}
return pieces;
}
/* From documentation:
* https://github.com/brendan-duncan/image/blob/main/doc/flutter.md#convert-a-flutter-asset-to-the-dart-image-library
*/
Future<imglib.Image?> decodeAsset(String path) async {
final data = await rootBundle.load(path);
// Utilize flutter's built-in decoder to decode asset images as it will be
// faster than the dart decoder.
final buffer = await ui.ImmutableBuffer.fromUint8List(
data.buffer.asUint8List());
final id = await ui.ImageDescriptor.encoded(buffer);
final codec = await id.instantiateCodec(
targetHeight: id.height,
targetWidth: id.width);
final fi = await codec.getNextFrame();
final uiImage = fi.image;
final uiBytes = await uiImage.toByteData();
final image = imglib.Image.fromBytes(width: id.width, height: id.height,
bytes: uiBytes!.buffer, numChannels: 4);
return image;
}
© 2022 - 2024 — McMap. All rights reserved.