Flutter 的图片裁剪插件
该插件附带一个Crop小部件。该小部件仅渲染图像、叠加层和用于裁剪图像的句柄。因此,它可以与其他小部件组合以构建自定义图像裁剪体验。
使用
- 创建一个小部件来加载和编辑图像:
ini
final cropKey = GlobalKey<CropState>();
less
Widget _buildCropImage() {
return Container(
color: Colors.black,
padding: const EdgeInsets.all(20.0),
child: Crop(
key: cropKey,
image: Image.file(imageFile),
aspectRatio: 4.0 / 3.0,
),
);
}
- 访问裁剪值:
- 比例是裁剪时按比例缩放图像宽度和高度的一个因素。1.0不需要比例。
- 区域是一个矩形,表示图像上要裁剪的分数位置。
inifinal crop = cropKey.currentState; // or // final crop = Crop.of(context); final scale = crop.scale; final area = crop.area; if (area == null) { // cannot crop, widget is not setup // ... }
-
访问和处理图像。作为请求访问照片权限的便捷功能。
final permissionsGranted = await ImageCrop.requestPermissions();
-
读取图像选项,例如:宽度和高度。这是一种高效的实现,无需解码或将实际图像加载到内存中。
cssfinal options = await getImageOptions(file: file); debugPrint('image width: ${options.width}, height: ${options.height}');
- 如果要将大图像加载到内存中,则有一个采样函数依赖于本机平台按比例缩小图像,然后再将其加载到内存中。例如,重新采样图像以1024x4096尽可能接近尺寸。如果它是正方形,preferredSize则可以使用它来指定宽度和高度。在 UI 中显示图像时最好利用此功能。
yamlfinal sampleFile = await ImageCrop.sampleImage( file: originalFile, preferredWidth: 1024, preferredHeight: 4096, );
- 一旦Crop小部件准备就绪,就会提供对图像的裁剪和缩放的原生支持。为了生成更高质量的裁剪图像,请依靠具有首选最大宽度和高度的采样图像。放大采样图像的分辨率。裁剪后,图像的分辨率更高。示例如下:
lessfinal sampledFile = await ImageCrop.sampleImage( file: originalFile, preferredWidth: (1024 / crop.scale).round(), preferredHeight: (4096 / crop.scale).round(), ); final croppedFile = await ImageCrop.cropImage( file: sampledFile, area: crop.area, );
鸿蒙OS关键代码
###裁剪方法
ini
private async cropImage(result: MethodResult, path: string, scale: number, left: number, top: number, right: number, bottom: number) {
let imageSource = image.createImageSource(path);
let pixelMapData = await imageSource.createPixelMap();
let options = await this.decodeImageOptions(imageSource);
if (options.isFlippedDimensions()) {
await pixelMapData.rotate(options.getDegrees());
}
let width = options.getWidth() * (right - left) * scale;
let height = options.getHeight() * (bottom - top) * scale;
let region: image.Region = {
x: options.getWidth() * left, y: options.getHeight() * top, size: {
height: height, width: width
}
};
await pixelMapData.crop(region);
let dstFile = this.createTemporaryImageFilePath();
await this.savaPixelMap(pixelMapData, dstFile);
await imageSource.release();
result.success(dstFile);
}
缩略图采样
typescript
private async sampleImage(result: MethodResult, path: string, maximumWidth: number, maximumHeight: number) {
let imageSource = image.createImageSource(path);
let options = await this.decodeImageOptions(imageSource);
// 缩略图采样大小,当前只能取1。
let inSampleSize = 1;//this.calculateInSampleSize(options.getWidth(), options.getHeight(), maximumWidth, maximumHeight);
let pixelMapData = await imageSource.createPixelMap({sampleSize: inSampleSize});
if (options.getWidth() > maximumWidth && options.getHeight() > maximumHeight) {
let ratio = Math.max(maximumWidth / options.getWidth(), maximumHeight / options.getHeight());
await pixelMapData.scale(ratio, ratio);
}
let dstFile = this.createTemporaryImageFilePath();
await this.savaPixelMap(pixelMapData, dstFile);
await imageSource.release()
// await this.copyExif(path, dstFile); //此方法OHOS接口暂时支持有问题 等新版本在验证
result.success(dstFile);
}
获取图片属性
csharp
private async getImageOptions(path: string, result: MethodResult) {
let source = image.createImageSource(path);
let options = await this.decodeImageOptions(source);
let properties = new HashMap<string, number>();
properties.set("width", options.getWidth());
properties.set("height", options.getHeight());
await source.release();
result.success(properties);
}