ugu11 / camera_tutorial

Apache License 2.0
36 stars 11 forks source link

iOS error #1

Closed GanZhiXiong closed 4 years ago

GanZhiXiong commented 4 years ago

device: iPhone6s plus iOS version: 13.3.1

Launching lib/main.dart on 干志雄的 iPhone in debug mode...
Found saved certificate choice "iPhone Developer: Guangjian Wang (N8AC8H42N4)". To clear, use "flutter config".
Signing iOS app for device deployment using developer identity: "iPhone Developer: Guangjian Wang (N8AC8H42N4)"
Running Xcode build...
Xcode build done.                                           13.1s
Installing and launching...                                        18.4s
Debug service listening on ws://localhost:1024/ws
Syncing files to device 干志雄的 iPhone...
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════

flutter: The following ArgumentError was thrown building Builder:

flutter: Invalid argument(s): Failed to lookup symbol (dlsym(RTLD_DEFAULT, convertImage): symbol not found)

flutter: 

flutter: The relevant error-causing widget was:

flutter:   MaterialApp

flutter:   file:///Users/ganzhixiong/Documents/yilisheng/TemperatureSensor/test/camera_tutorial-master.zip%20Folder/camera_tutorial-master/lib/main.dart:23:12

flutter: 

flutter: When the exception was thrown, this was the stack:

flutter: #0      DynamicLibrary.lookup (dart:ffi-patch/ffi_dynamic_library_patch.dart:33:29)

flutter: #1      _MyHomePageState.initState (package:camera_tutorial/main.dart:57:28)

flutter: #2      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4644:58)

flutter: #3      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4480:5)

flutter: ...     Normal element mounting (24 frames)

flutter: #27     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3450:14)

flutter: #28     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5951:32)

flutter: ...     Normal element mounting (119 frames)

flutter: #147    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3450:14)

flutter: #148    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5951:32)

flutter: ...     Normal element mounting (261 frames)

flutter: #409    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3450:14)

flutter: #410    Element.updateChild (package:flutter/src/widgets/framework.dart:3218:18)

flutter: #411    RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1129:16)

flutter: #412    RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1100:5)

flutter: #413    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1042:17)

flutter: #414    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2607:19)

flutter: #415    RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1041:13)

flutter: #416    WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:922:7)

flutter: #417    WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:903:7)

flutter: (elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)

flutter: 

flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════

Lost connection to device.
ugu11 commented 4 years ago

Thanks for letting me know. I'll work on it :)

ugu11 commented 4 years ago

@GanZhiXiong I believe this issue is fixed in the last commit (f5c36d5) . Also, in the article I added an extra step to the section 3.1.2 regarding this issue. I'll be waiting for feedback before closing this :)

GanZhiXiong commented 4 years ago

iOS info.plist must add this code

<!-- 相机 -->
<key>NSCameraUsageDescription</key>
<string>App需要您的同意,才能访问相机</string>   

Otherwise the following error will be reported [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.

GanZhiXiong commented 4 years ago

@Hugand
tap FloatingActionButton error

image

GanZhiXiong commented 4 years ago

@Hugand

In iOS, cameraImage.format is bgra8888. For android cameraImage.format is yuv420. I can get the right picture on my iOS device with this link code https://gist.github.com/Alby-o/fe87e35bc21d534c8220aed7df028e03

in iOS, use ResolutionPreset.medium, The test results are still slow Here are the test results

flutter: convert to BGRA8888: 1054ms
flutter: convert to BGRA8888: 1047ms
flutter: convert to BGRA8888: 942ms
flutter: convert to BGRA8888: 811ms
flutter: convert to BGRA8888: 834ms
flutter: convert to BGRA8888: 983ms
flutter: convert to BGRA8888: 948ms
flutter: convert to BGRA8888: 837ms
flutter: convert to BGRA8888: 915ms
flutter: convert to BGRA8888: 926ms
flutter: convert to BGRA8888: 821ms
flutter: convert to BGRA8888: 818ms
flutter: convert to BGRA8888: 902ms
flutter: convert to BGRA8888: 809ms
flutter: convert to BGRA8888: 822ms
flutter: convert to BGRA8888: 894ms
flutter: convert to BGRA8888: 877ms
flutter: convert to BGRA8888: 925ms
flutter: convert to BGRA8888: 982ms
flutter: convert to BGRA8888: 871ms
flutter: convert to BGRA8888: 959ms

Here is the test code

        Stopwatch stopwatch = Stopwatch();
        stopwatch.start();
        _imageData = await convertImagetoPng(_cameraImage);
        stopwatch.stop();
        print('convert to BGRA8888: ${stopwatch.elapsedMilliseconds}ms');

I think imglib may be the reason for the slowness

ugu11 commented 4 years ago

Oh yeah, on the ios the format is different. I remember seeing it somewhere. Yeah, I believe it is because you create an Image object with Image.fromBytes() and then you encode it to png and that really takes some time. If there was a way to directly encode to png without the Image.fromBytes() would be nice

GanZhiXiong commented 4 years ago

@Hugand After testing, it was found that the convert to was slow my test code

Future<List<int>> convertImagetoPng(CameraImage image) async {
  try {
    Stopwatch stopwatch = Stopwatch();
    stopwatch.start();
    imglib.Image img;
    if (image.format.group == ImageFormatGroup.yuv420) {
      img = _convertYUV420(image);
    } else if (image.format.group == ImageFormatGroup.bgra8888) {
      img = _convertBGRA8888(image);
    }
    stopwatch.stop();
    print('convert: ${stopwatch.elapsedMilliseconds}ms');

    stopwatch.reset();
    stopwatch.start();
    imglib.PngEncoder pngEncoder = new imglib.PngEncoder();
    // Convert to png, this code slow
    List<int> png = pngEncoder.encodeImage(img);
    stopwatch.stop();
    print('convert to png: ${stopwatch.elapsedMilliseconds}ms');
    return png;
  } catch (e) {
    print(">>>>>>>>>>>> ERROR:" + e.toString());
  }
  return null;
}

// CameraImage BGRA8888 -> PNG
// Color
imglib.Image _convertBGRA8888(CameraImage image) {
  return imglib.Image.fromBytes(
    image.width,
    image.height,
    image.planes[0].bytes,
    format: imglib.Format.bgra,
  );
}
Stopwatch stopwatch = Stopwatch();
stopwatch.start();
_imageData = await convertImagetoPng(_cameraImage);
stopwatch.stop();
print('convert to BGRA8888: ${stopwatch.elapsedMilliseconds}ms');

test result image

ugu11 commented 4 years ago

@GanZhiXiong Have you tried converting it to JPEG instead of PNG? It might be a little bit faster

GanZhiXiong commented 4 years ago

The conversion to jpeg was much faster,convert to jpeg It's basically no more than 400ms code add as follow

imglib.JpegEncoder jpegEncoder = imglib.JpegEncoder();
    // Conver to jpeg
    List<int> jpeg = jpegEncoder.encodeImage(img);
    stopwatch.stop();
    print('convert to jpeg: ${stopwatch.elapsedMilliseconds}ms');

test result image

GanZhiXiong commented 4 years ago

Thank you, I temporarily solve this problem by converting to jpeg 👍👍👍 cool

ugu11 commented 4 years ago

Awesome! You're welcome :) By the way, which resolution are you using?

GanZhiXiong commented 4 years ago

using ResolutionPreset.medium

CellCS commented 3 years ago

@GanZhiXiong ,

May i ask whether you try veryHigh in iOS (1080*1920)? whether exception happens

"[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: RangeError (index): Index out of range: index should be less than 8294400: 8294400"

in

    if (Platform.isIOS) {
      img = imgLib.Image.fromBytes(
        image.width, //image.planes[0].bytesPerRow,
        image.height,
        image.planes[0].bytes,
        format: imgLib.Format.bgra,
      );

here image.planes[0].bytesPerRow is 4352, image.width is 1080.

if is using image.planes[0].bytesPerRow to solve excetpion, time is becoming costy. Thanks