【问题标题】:Flutter: ImagePicker: await picker.pickImage(source: ImageSource.gallery) doesn't return颤振:ImagePicker:等待picker.pickImage(来源:ImageSource.gallery)不返回
【发布时间】:2022-01-14 17:02:35
【问题描述】:

当我触发pickimage功能时,它会弹出图库视图以选择图像。当我选择一张图片时,应用程序会返回到应用程序视图。但是 pickimage 函数不会返回,并且永远挂起。 这是我的代码:


import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:google_ml_kit/google_ml_kit.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Text Scanning Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  late String result;
  File? _image;
  InputImage? inputImage;
  final ImagePicker picker = ImagePicker();

  Future pickImageFromGallery() async {
    print("starting get image");
    final XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);
    //final pickedFile = await picker.pickImage(source: ImageSource.gallery);
    print("getting image.....");
    setState(() {
      if (pickedFile != null) {
        print("file not null");
        _image = File(pickedFile.path);
        inputImage = InputImage.fromFilePath(pickedFile.path);

        imageToText(inputImage);
      } else {
        print('No image selected.');
      }
    });
  }

  Future captureImageFromCamera() async {
    final pickedFile = await picker.pickImage(source: ImageSource.camera);
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
        inputImage = InputImage.fromFilePath(pickedFile.path);
        imageToText(inputImage);
      } else {
        print('No image selected.');
      }
    });
  }

  Future imageToText(inputImage) async {
    print("starting");
    result = '';

    final textDetector = GoogleMlKit.vision.textDetector();
    print("loaded textDetector");
    final RecognisedText recognisedText = await textDetector.processImage(inputImage);
    print("loaded recognisedText");

    setState(() {
      String text = recognisedText.text;
      for (TextBlock block in recognisedText.blocks) {
        //each block of text/section of text
        final String text = block.text;
        print("block of text: ");
        print(text);
        for (TextLine line in block.lines) {
          //each line within a text block
          for (TextElement element in line.elements) {
            //each word within a line
            result += element.text + " ";
          }
        }
      }
      result += "\n\n";
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              width: 100,
              child: TextField(
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.black),
              ),
            ),
            Container(
                height: 70,
                width: 150,
                child: TextButton(
                  style: TextButton.styleFrom(
                    primary: Colors.blue,
                  ),
                  onPressed: () {
                    pickImageFromGallery();
                  },
                  child: Text('Pick Image'),
                ))
          ],
        ),
      ),
      // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

这是我的 pubspec.yaml

name: text_scanning
description: A new Flutter project.


publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
  sdk: ">=2.14.0-0 <3.0.0"


dependencies:
  flutter:
    sdk: flutter
  font_awesome_flutter: ^9.0.0
  splash_screen_view: ^3.0.0
  cupertino_icons: ^1.0.2
  google_ml_kit: ^0.7.3
  image_picker: ^0.8.1+1

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^1.0.0


flutter:

  uses-material-design: true

这是 podfile

# Uncomment this line to define a global platform for your project
platform :ios, '10.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
  pod 'GoogleMLKit/TextRecognition'
  pod 'Firebase'
end

post_install do |installer|
  # add these lines:
  installer.pods_project.build_configurations.each do |config|
    config.build_settings["EXCLUDED_ARCHS[sdk=*]"] = "armv7"
    config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion
  end

  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    # add these lines:
    target.build_configurations.each do |config|
      if Gem::Version.new($iOSVersion) > Gem::Version.new(config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'])
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion
      end
    end
  end
end

这是我在 xcode 中的信息截图: [注意画廊和相机的隐私][1]

我在这里束手无策,我遵循了每个文档,它甚至没有产生任何错误,只是挂在那里。 [1]:https://i.stack.imgur.com/XC6aP.png

【问题讨论】:

  • 您确定 imagePicker 功能失败还是 mlkit 功能可能有问题?
  • 我用打印语句进行了测试。它不适合 ImageToText 函数。它转到pickImage,但下一个打印语句永远不会打印。
  • 在某些情况下,图像文件太大,某些算法无法处理。尝试使用较低的质量。您可以在图像选择器功能本身中指定。另一个提示:不要在大块代码周围使用 setstate,而应仅在应该在 ui 中更新的变量周围使用它。
  • 我遇到了同样的问题。我发现当我包含 google_ml_kit 依赖项时,当我从 pubspec 中删除它(并注释掉相关代码)时,这个 only 发生,图像选择器工作得很好并返回。另外,至少在我的情况下,这个问题只发生在 iOS 平台上。 @HarryWang 关于这个原因的任何线索?

标签: ios flutter image


【解决方案1】:

您是否在基于 ARM 的 Mac (M1 / M1 Pro) 上的 iOS 模拟器上运行此代码? 如果是这样,那么问题可能源于 iOS 模拟器中的当前错误,该错误似乎仅在使用 Rosetta 翻译运行时才会重现(阅读更多 herehere)。

在您的情况下,pubspec.yaml 文件将 google_ml_kit 声明为依赖项,这会强制应用使用 Rosetta 运行,从而破坏 image_picker 插件。

Apple 可能会在未来某个时间解决此问题,但与此同时,您可以通过在物理 iOS 设备上运行您的应用程序来解决此问题,使用带有 iOS 版本的 iOS 模拟器

这样做:

  1. 打开 Xcode
  2. 转到首选项。
  3. 选择“组件”选项卡。
  4. 标记您想要的模拟器。
  5. 按“立即检查并安装”。

然后:

  1. 打开模拟器应用程序。
  2. 选择文件 > 新建模拟器
  3. 选择您喜欢的设备,并确保选择 iOS 版本

【讨论】:

  • 我试过了。它不起作用。当我尝试选择图像时它会崩溃。我得到“与设备的连接丢失”
猜你喜欢
  • 2020-10-25
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 2023-04-07
  • 1970-01-01
  • 2021-09-14
  • 2020-05-06
相关资源
最近更新 更多