Flutter : 画像の切り抜き
Flutter + Firebase でアプリ作成のためのパーツあつめ。
まで、Android、iOSでの簡易動作確認ができたので、画像切り抜きパッケージ、image_cropper を試す。
1.例によってエラー対応
pub.devのimage_cropperページのExampleに従い、コードを記述し実行するが、androidx.core.widget.TintableCompoundDrawableView が存在しないエラー
I/pea.favo_phras( 6224): Rejecting re-init on previously-failed class java.lang.Class: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/widget/TintableCompoundDrawablesView; I/pea.favo_phras( 6224): at java.lang.Object java.lang.Class.newInstance() (Class.java:-2) I/pea.favo_phras( 6224): at android.app.Activity android.app.AppComponentFactory.instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent) (AppComponentFactory.java:69) I/pea.favo_phras( 6224): at android.app.Activity androidx.core.app.CoreComponentFactory.instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent) (CoreComponentFactory.java:43)
image_cropper のGithubのissueに同じ事象の報告および解決策情報あり。
https://github.com/hnvn/flutter_image_cropper/issues/78
build.gradle の dependencies に以下を追記
implementation ‘androidx.core:core:1.0.2’
implementation ‘androidx.appcompat:appcompat:1.0.2’
とのことだが、それだけでは解決しないため、エラーログを見ながら以下のように調整。
AndroAndroidXの互換性対応で、この手のエラー解決のコツがなんとなくつかめてきたが、、、若干不安。
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-analytics:16.0.0'
implementation 'androidx.core:core:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
print(details.requested.group)
if (details.requested.group ==~ /^androidx\.(core|viewpager|drawlayout|interpolator|fragment|versionedparcelable|appcompat)/
) {
details.useVersion '1.0.0'
details.because 'API needs higher versions'
}
if (details.requested.group == 'androidx.lifecycle'
) {
details.useVersion '2.1.0'
details.because 'API needs higher versions'
}
}
}
2.Flutter
上記エラー対応によって、pub.devのimage_cropperページのExampleのコードが動いた。
2.1 pubspec.yaml(/)
に以下を追記
dependencies:
:
image_cropper: ^1.1.0
2.2 AndroidManifest.xml(/android/app/main/res)
に以下のActivityを追加。
<application>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
</application>
2.3 ソースコード
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
class SecondRoute extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _SecondRoute();
}
}
class _SecondRoute extends State<SecondRoute>{
Image _image = Image.network('https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg');
Future _handleImageCrop(BuildContext context) async {
var imageFile = await ImagePicker.pickImage(source: ImageSource.camera);
var croppedFile = await ImageCropper.cropImage(
sourcePath: imageFile.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
androidUiSettings: AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: Colors.deepOrange,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
iosUiSettings: IOSUiSettings(
minimumAspectRatio: 1.0,
)
);
setState(() {
_image = Image.file(croppedFile);
});
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(
children: <Widget>[
Container(
// A fixed-height child.
color: const Color.fromARGB(255, 255, 255, 255),
height: 120.0,
),
Expanded(
// A flexible child that will grow to fit the viewport but
// still be at least as big as necessary to fit its contents.
child: Container(
color: const Color(0xffffffff),
height: 240.0,
constraints: BoxConstraints(
minWidth: viewportConstraints.maxWidth,
minHeight: double.infinity
),
child: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
_handleImageCrop(context);
},
child: Text('Image Crop'),
),
RaisedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Back'),
),
_image,
],
),
),
),
],
),
),
),
);
},
);
}
}
3.実行
3.1 Android
「Image Crop」ボタン押下で、_handleImageCrop() を呼び出し、画像選択 を経由(カメラを起動)して取得したファイル
var imageFile = await ImagePicker.pickImage(source: ImageSource.camera);
を、
var croppedFile = await ImageCropper.cropImage()
に引き渡す。
画像を切り抜く
範囲を選択し、画面右上のチェック
切り抜かれた範囲を画面に表示。OK!!
3.2 iOS
Android同様のことをiPhoneエミュレーターで。
特に変更はなし。
・・・エミュレータのため、カメラ起動できないようで、OKでエラーになるので、
var imageFile = await ImagePicker.pickImage(source: ImageSource.camera);
を
var imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
に変更して確認
Android同様に画像の切り抜きUIが起動。
Doneで、選択部分が画面表示された!
Flutterもエラーの嵐でうんざりしかけたが、AndroAndroidXの互換性対応で、何とか乗り切れそうか!?
macの操作がぎこちないので、本でも買おうかしら。

