mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 04:49:21 +00:00
Can crop image
This commit is contained in:
parent
2a00530126
commit
ea45bf828c
@ -14,6 +14,7 @@
|
|||||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||||
|
|
||||||
|
<!-- This is required on Android 11+ for image picker -->
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
||||||
@ -69,5 +70,11 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<!-- This let the image cropper work -->
|
||||||
|
<activity
|
||||||
|
android:name="com.yalantis.ucrop.UCropActivity"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:comunic/ui/dialogs/record_audio_dialog.dart';
|
import 'package:comunic/ui/dialogs/record_audio_dialog.dart';
|
||||||
|
import 'package:comunic/ui/routes/image_editor_route.dart';
|
||||||
import 'package:comunic/utils/files_utils.dart';
|
import 'package:comunic/utils/files_utils.dart';
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:comunic/utils/ui_utils.dart';
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
@ -132,6 +133,8 @@ Future<BytesFile> showPickFileDialog({
|
|||||||
|
|
||||||
file = BytesFile(image.path.split("/").last, await image.readAsBytes());
|
file = BytesFile(image.path.split("/").last, await image.readAsBytes());
|
||||||
|
|
||||||
|
file = await showImageCropper(context, file);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Pick an video
|
// Pick an video
|
||||||
|
53
lib/ui/routes/image_editor_route.dart
Normal file
53
lib/ui/routes/image_editor_route.dart
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:comunic/models/api_request.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:comunic/utils/log_utils.dart';
|
||||||
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:image_cropper/image_cropper.dart';
|
||||||
|
|
||||||
|
import '../../models/api_request.dart';
|
||||||
|
import '../../utils/files_utils.dart';
|
||||||
|
|
||||||
|
/// Image cropper route
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
/// Attempt to crop image
|
||||||
|
///
|
||||||
|
/// Return original image in case of error / if the user did not crop the image
|
||||||
|
Future<BytesFile> showImageCropper(
|
||||||
|
BuildContext context, BytesFile source) async {
|
||||||
|
assert(context != null);
|
||||||
|
assert(source != null);
|
||||||
|
|
||||||
|
File file;
|
||||||
|
File cropped;
|
||||||
|
|
||||||
|
try {
|
||||||
|
file = await generateTemporaryFile();
|
||||||
|
await file.writeAsBytes(source.bytes);
|
||||||
|
|
||||||
|
File cropped = await ImageCropper.cropImage(
|
||||||
|
sourcePath: file.absolute.path,
|
||||||
|
compressFormat: ImageCompressFormat.png,
|
||||||
|
androidUiSettings: AndroidUiSettings(
|
||||||
|
toolbarColor: Colors.black,
|
||||||
|
toolbarTitle: tr("Crop Photo"),
|
||||||
|
toolbarWidgetColor: Colors.white,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (cropped == null) return null;
|
||||||
|
|
||||||
|
return BytesFile("cropped.png", await cropped.readAsBytes());
|
||||||
|
} catch (e, s) {
|
||||||
|
logError(e, s);
|
||||||
|
snack(context, tr("Failed to execute image cropper!"));
|
||||||
|
return source;
|
||||||
|
} finally {
|
||||||
|
if (file != null && await file.exists()) file.delete();
|
||||||
|
if (cropped != null && await cropped.exists()) cropped.delete();
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,11 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:random_string/random_string.dart';
|
||||||
|
|
||||||
/// Files utilities
|
/// Files utilities
|
||||||
///
|
///
|
||||||
@ -46,6 +51,16 @@ Future<PickedFile> pickImage(BuildContext context) async {
|
|||||||
: ImageSource.gallery);
|
: ImageSource.gallery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a new temporary file
|
||||||
|
///
|
||||||
|
/// Throws in case of failure
|
||||||
|
Future<File> generateTemporaryFile() async {
|
||||||
|
final tempDir = await getTemporaryDirectory();
|
||||||
|
if (tempDir == null)
|
||||||
|
throw Exception("Could not generate temporary directory!");
|
||||||
|
return File(path.join(tempDir.path, randomString(15, from: 65, to: 90)));
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if a mime type maps to an image or not
|
/// Check if a mime type maps to an image or not
|
||||||
bool isImage(String mimeType) => mimeType.startsWith("image/");
|
bool isImage(String mimeType) => mimeType.startsWith("image/");
|
||||||
|
|
||||||
|
@ -3,11 +3,10 @@ import 'dart:io';
|
|||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:comunic/utils/log_utils.dart';
|
import 'package:comunic/utils/log_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:path/path.dart' as path;
|
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
import 'package:random_string/random_string.dart';
|
|
||||||
import 'package:video_thumbnail/video_thumbnail.dart';
|
import 'package:video_thumbnail/video_thumbnail.dart';
|
||||||
|
|
||||||
|
import 'files_utils.dart';
|
||||||
|
|
||||||
/// Video utilities
|
/// Video utilities
|
||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
@ -20,9 +19,7 @@ Future<BytesFile> generateVideoThumbnail({
|
|||||||
File file;
|
File file;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final tempDir = await getTemporaryDirectory();
|
file = await generateTemporaryFile();
|
||||||
if (tempDir == null) return null;
|
|
||||||
file = File(path.join(tempDir.path, randomString(15, from: 65, to: 90)));
|
|
||||||
|
|
||||||
await file.writeAsBytes(videoFile.bytes);
|
await file.writeAsBytes(videoFile.bytes);
|
||||||
|
|
||||||
|
@ -282,6 +282,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.19"
|
version: "2.1.19"
|
||||||
|
image_cropper:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image_cropper
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
image_picker:
|
image_picker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -123,6 +123,9 @@ dependencies:
|
|||||||
# Color picker
|
# Color picker
|
||||||
flutter_colorpicker: ^0.3.5
|
flutter_colorpicker: ^0.3.5
|
||||||
|
|
||||||
|
# Image cropper
|
||||||
|
image_cropper: ^1.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
Loading…
Reference in New Issue
Block a user