Skip to content

Commit

Permalink
Merge pull request #39 from weta-vn/dev_/hotfix20211015
Browse files Browse the repository at this point in the history
Dev /hotfix20211015
  • Loading branch information
weta-vn authored Oct 17, 2021
2 parents 98c1852 + fc14b0a commit 7861e7a
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 69 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## [0.1.5+5]

* **Fixbugs:**
* Check permission for camera & photo gallery
* Fixbug about OCR text editting

## [0.1.5+1]

* **New features:**
Expand Down
4 changes: 2 additions & 2 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ analyzer:
# Don't cast implicitly.
implicit-casts: false
# Don't fall back to 'dynamic' implicitly.
implicit-dynamic: false
# implicit-dynamic: false
errors:
# Without ignore here, we cause import of all_lint_rules to warn, because some rules conflict.
# We explicitly enabled even conflicting rules and are fixing the conflicts in this file.
included_file_warning: ignore

# Treat missing required parameters as an error, not as a hint or a warning.
missing_required_param: error
# missing_required_param: error

# Treat missing returns as an error, not as a hint or a warning.
missing_return: error
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
<string>9.0</string>
</dict>
</plist>
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/photo_manager/ios"

SPEC CHECKSUMS:
camera: 3164201dc344383e62282964016528c4f5a9ad50
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
camera: b9eb73c055259c6f808a9da4a0d43780f6645281
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
flutter_native_image: 9c0b7451838484458e5b0fae007b86a4c2d4bdfe
image_cropper: f1668dd8d2cad2d357955caad15a40547856edcb
image_editor: c1d038630eedea60d2dee9c14f36aa66c7f9cfab
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
path_provider: d1e9807085df1f9cc9318206cd649dc0b76be3de
photo_manager: 84fa94fbeb82e607333ea9a13c43b58e0903a463
TOCropViewController: 3105367e808b7d3d886a74ff59bf4804e7d3ab38

PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c

COCOAPODS: 1.10.1
COCOAPODS: 1.11.0
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.1.5+1"
version: "0.1.5+5"
archive:
dependency: transitive
description:
Expand Down
20 changes: 20 additions & 0 deletions lib/configs/image_picker_configs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,26 @@ class ImagePickerConfigs {
/// Defaults to "OCR".
String get textOCR => getTranslatedString("image_picker_ocr", "OCR");

/// Get localized text for label "image_picker_request_permission".
///
/// Defaults to "Request Permission".
String get textRequestPermission => getTranslatedString(
"image_picker_request_permission", "Request Permission");

/// Get localized text for label "image_picker_request_camera_permission".
///
/// Defaults to "You need allow camera permission.".
String get textRequestCameraPermission => getTranslatedString(
"image_picker_request_camera_permission",
"You need allow camera permission.");

/// Get localized text for label "image_picker_request_gallery_permission".
///
/// Defaults to "You need allow photo gallery permission.".
String get textRequestGalleryPermission => getTranslatedString(
"image_picker_request_gallery_permission",
"You need allow photo gallery permission.");

/// Translate string by translateFunc.
String getTranslatedString(String name, String defaultValue) {
return translateFunc.call(name, defaultValue);
Expand Down
207 changes: 149 additions & 58 deletions lib/widgets/picker/image_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ class _ImagePickerState extends State<ImagePicker>
/// Flag indicating state of image selecting.
bool _isImageSelectedDone = false;

/// Flag indicating status of permission to access cameras
bool _isCameraPermissionOK = false;

/// Flag indicating status of permission to access photo libray
bool _isGalleryPermissionOK = false;

/// Image configuration.
ImagePickerConfigs _configs = ImagePickerConfigs();

Expand Down Expand Up @@ -228,16 +234,20 @@ class _ImagePickerState extends State<ImagePicker>
Future<void> _initPhotoCapture() async {
LogUtils.log("[_initPhotoCapture] start");

// List all cameras in current device.
_cameras = await availableCameras();

// Select new camera for capturing.
if (_cameras.isNotEmpty) {
final CameraDescription? newDescription = _getCamera(
_cameras, _getCameraDirection(_configs.cameraLensDirection));
if (newDescription != null) {
await _onNewCameraSelected(newDescription);
try {
// List all cameras in current device.
_cameras = await availableCameras();

// Select new camera for capturing.
if (_cameras.isNotEmpty) {
final CameraDescription? newDescription = _getCamera(
_cameras, _getCameraDirection(_configs.cameraLensDirection));
if (newDescription != null) {
await _onNewCameraSelected(newDescription);
}
}
} on CameraException catch (e) {
LogUtils.log('Camera error ${e.code}, ${e.description}');
}
}

Expand Down Expand Up @@ -265,6 +275,43 @@ class _ImagePickerState extends State<ImagePicker>
}
}

/// Initialize current selected camera
void _initCameraController() {
// Create future object for initializing new camera controller.
final cameraController = _controller!;
_initializeControllerFuture =
cameraController.initialize().then((value) async {
LogUtils.log("[_onNewCameraSelected] cameraController initialized.");

_isCameraPermissionOK = true;

// After initialized, setting zoom & exposure values
await Future.wait([
cameraController.lockCaptureOrientation(DeviceOrientation.portraitUp),
cameraController.setFlashMode(_configs.flashMode),
cameraController
.getMinExposureOffset()
.then((value) => _minAvailableExposureOffset = value),
cameraController
.getMaxExposureOffset()
.then((value) => _maxAvailableExposureOffset = value),
cameraController
.getMaxZoomLevel()
.then((value) => _maxAvailableZoom = value),
cameraController
.getMinZoomLevel()
.then((value) => _minAvailableZoom = value),
]);

// Refresh screen for applying new updated
if (mounted) {
setState(() {});
}
}).catchError((e) {
LogUtils.log('Camera error ${e.toString()}');
});
}

/// Select new camera for capturing
Future<void> _onNewCameraSelected(CameraDescription cameraDescription) async {
LogUtils.log("[_onNewCameraSelected] start");
Expand All @@ -281,64 +328,44 @@ class _ImagePickerState extends State<ImagePicker>
);
_controller = cameraController;

// Init selected camera
_initCameraController();

// If the controller is updated then update the UI.
cameraController.addListener(() {
_controller!.addListener(() {
if (mounted) setState(() {});
if (cameraController.value.hasError) {
LogUtils.log('Camera error ${cameraController.value.errorDescription}');
}
});

// Create future object for initializing new camera controller.
try {
_initializeControllerFuture =
cameraController.initialize().then((value) async {
LogUtils.log("[_onNewCameraSelected] cameraController initialized.");

// After initialized, setting zoom & exposure values
await Future.wait([
cameraController.lockCaptureOrientation(DeviceOrientation.portraitUp),
cameraController.setFlashMode(_configs.flashMode),
cameraController
.getMinExposureOffset()
.then((value) => _minAvailableExposureOffset = value),
cameraController
.getMaxExposureOffset()
.then((value) => _maxAvailableExposureOffset = value),
cameraController
.getMaxZoomLevel()
.then((value) => _maxAvailableZoom = value),
cameraController
.getMinZoomLevel()
.then((value) => _minAvailableZoom = value),
]);

// Refresh screen for applying new updated
if (mounted) {
setState(() {});
}
});
} on CameraException catch (e) {
LogUtils.log('Camera error ${e.code}, ${e.description}');
}
}

/// Init photo gallery for image selecting
Future<void> _initPhotoGallery() async {
LogUtils.log("[_initPhotoGallery] start");

// Request permission for image selecting
final result = await PhotoManager.requestPermission();
if (result) {
// Get albums then set first album as current album
_albums = await PhotoManager.getAssetPathList(type: RequestType.image);
if (_albums.isNotEmpty) {
final isAllAlbum = _albums.firstWhere((element) => element.isAll,
orElse: () => _albums.first);
setState(() {
_currentAlbum = isAllAlbum;
});
try {
// Request permission for image selecting
final result = await PhotoManager.requestPermissionExtend();
if (result.isAuth) {
LogUtils.log('PhotoGallery permission allowed');

_isGalleryPermissionOK = true;

// Get albums then set first album as current album
_albums = await PhotoManager.getAssetPathList(type: RequestType.image);
if (_albums.isNotEmpty) {
final isAllAlbum = _albums.firstWhere((element) => element.isAll,
orElse: () => _albums.first);
setState(() {
_currentAlbum = isAllAlbum;
});
}
} else {
LogUtils.log('PhotoGallery permission not allowed');
}
} catch (e) {
LogUtils.log('PhotoGallery error ${e.toString()}');
}
}

Expand Down Expand Up @@ -607,9 +634,13 @@ class _ImagePickerState extends State<ImagePicker>
return Stack(children: [
SizedBox(height: size.height, width: size.width),
if (_mode == PickerMode.Camera)
Center(child: _buildCameraPreview(context))
_isCameraPermissionOK
? Center(child: _buildCameraPreview(context))
: _buildCameraRequestPermissionView(context)
else
_buildAlbumPreview(context),
_isGalleryPermissionOK
? _buildAlbumPreview(context)
: _builGalleryRequestPermissionView(context),
if (_mode == PickerMode.Camera) ...[
Positioned(
bottom: bottomHeight.toDouble(),
Expand Down Expand Up @@ -778,6 +809,37 @@ class _ImagePickerState extends State<ImagePicker>
: container;
}

/// Build camera request permission view
Widget _buildCameraRequestPermissionView(BuildContext context) {
final size = MediaQuery.of(context).size;
final bottomHeight = (widget.maxCount == 1)
? (kBottomControlPanelHeight - 40)
: kBottomControlPanelHeight;
return SizedBox(
width: size.width,
height: size.height - bottomHeight,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.grey.shade400,
padding: const EdgeInsets.symmetric(horizontal: 12),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30)),
),
),
onPressed: _initCameraController,
child: Text(_configs.textRequestPermission,
style: const TextStyle(color: Colors.black)),
),
Text(_configs.textRequestCameraPermission,
style: const TextStyle(color: Colors.grey))
],
),
);
}

/// Build camera preview widget.
Widget _buildCameraPreview(BuildContext context) {
LogUtils.log("[_buildCameraPreview] start");
Expand Down Expand Up @@ -859,6 +921,33 @@ class _ImagePickerState extends State<ImagePicker>
});
}

/// Build camera request permission view
Widget _builGalleryRequestPermissionView(BuildContext context) {
final size = MediaQuery.of(context).size;
final bottomHeight = (widget.maxCount == 1)
? (kBottomControlPanelHeight - 40)
: kBottomControlPanelHeight;
return SizedBox(
width: size.width,
height: size.height - bottomHeight,
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.grey.shade400,
padding: const EdgeInsets.symmetric(horizontal: 12),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30)),
),
),
onPressed: _initPhotoGallery,
child: Text(_configs.textRequestPermission,
style: const TextStyle(color: Colors.black)),
),
Text(_configs.textRequestGalleryPermission,
style: const TextStyle(color: Colors.grey))
]));
}

/// Build album preview widget.
Widget _buildAlbumPreview(BuildContext context) {
LogUtils.log("[_buildAlbumPreview] start");
Expand Down Expand Up @@ -1344,9 +1433,11 @@ class _ImagePickerState extends State<ImagePicker>
groupValue: _mode,
onValueChanged: (dynamic val) async {
if (_mode != val) {
if (val == PickerMode.Camera && _cameras.isEmpty) {
if (val == PickerMode.Camera &&
(_cameras.isEmpty || !_isCameraPermissionOK)) {
await _initPhotoCapture();
} else if (val == PickerMode.Album && _albums.isEmpty) {
} else if (val == PickerMode.Album &&
(_albums.isEmpty || !_isGalleryPermissionOK)) {
await _initPhotoGallery();
}

Expand Down
6 changes: 4 additions & 2 deletions lib/widgets/viewer/image_viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -452,13 +452,15 @@ class _ImageViewerState extends State<ImageViewer>
final retImg = await ImageUtils.getImageInfo(image);

// Get detected objects
if (_configs.labelDetectFunc != null) {
if (_configs.labelDetectFunc != null &&
(retImg.recognitions?.isEmpty ?? true)) {
final objs = await _configs.labelDetectFunc!.call(retImg.modifiedPath);
if (objs.isNotEmpty) retImg.recognitions = objs;
}

// Get OCR from image
if (_configs.ocrExtractFunc != null) {
if (_configs.ocrExtractFunc != null &&
(retImg.ocrText?.isEmpty ?? true)) {
final text = await _configs.ocrExtractFunc!.call(retImg.modifiedPath);
if (text.isNotEmpty) retImg.ocrText = text;
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: advance_image_picker
description: Flutter plugin in pure Dart code for selecting/editing multiple images from the Android/iOS image library and taking new pictures with the camera in the same view.
version: 0.1.5+1
version: 0.1.5+5
homepage: https://freemar.vn
repository: https://github.com/weta-vn/advance_image_picker

Expand Down

0 comments on commit 7861e7a

Please sign in to comment.