Flutter + AWS:总是会出现管道破裂错误

时间:2018-12-07 19:34:53

标签: amazon-web-services dart flutter

我正在尝试将面孔与AWS rekognition API进行比较。但不知何故,我一直都在遇到“断管”错误。 aws键和照片没有问题。我正试图从http.post获取更多信息,但是不幸的是,它只说了“断管”,没有提供任何细节。

场景;

  • 用户拍摄2张照片(正在工作)
  • 第二秒,我将图像解析为字节(有效)
  • 将带有标准请求的字节发送到aws API(无效)

我也将图像质量更改为最低,但这没有帮助。


Main.dart代码

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

List<CameraDescription> cameras;

Future<void> main() async {
  cameras = await availableCameras();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  CameraController controller;

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras[0], ResolutionPreset.low);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  Future<String> _checkImage(String filePath, String secondPath) async {
    File sourceImagefile, targetImagefile; //load source and target images in those File objects
    String accessKey, secretKey, region ; //load your aws account info in those variables

    print(filePath);
    print(secondPath);

    targetImagefile = File(filePath);
    sourceImagefile = File(secondPath);

    print(targetImagefile.existsSync());
    print(sourceImagefile.existsSync());

    accessKey = '';
    secretKey = '';
    region = 'eu-west-1';

    RekognitionHandler rekognition = new RekognitionHandler(accessKey, secretKey, region);
    String labelsArray = await rekognition.compareFaces(sourceImagefile, targetImagefile);
    return labelsArray;
  }

  Widget cameraPart() {
    if (!controller.value.isInitialized) {
      return Container();
    }
    return AspectRatio(
        aspectRatio:
        controller.value.aspectRatio,
        child: CameraPreview(controller));
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: cameraPart(),
      floatingActionButton: FloatingActionButton(
        onPressed: takePhoto,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  Future<String> get360PhotoFolder() async {
    final Directory appFolder = await getAppFolder();
    final String dirPath = '${appFolder.path}/photos360';
    await Directory(dirPath).create(recursive: true);

    return dirPath;
  }

  String firstPath = '';
  String secondPath = '';

  Future<bool> takePhoto() async {
    final String dirPath = await get360PhotoFolder();
    final String filePath = '$dirPath/${timestamp()}_test.jpg';

    try {
      debugPrint('photo taken - $filePath');
      await controller.takePicture(filePath);

      setState(() {
        if (firstPath == '') {
          print('a');
          firstPath = filePath;
        }else if (secondPath == '') {
          print('b');
          secondPath = filePath;

          _checkImage(firstPath, secondPath).then((value) {
            print(value);
          }).catchError((error) {
            print(error);
          });
          firstPath = '';
          secondPath = '';
        }
      });
    } on CameraException catch (e) {
      print([e.code, e.description]);
      return true;
    }

    return false;
  }

  String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();

  Future<Directory> getAppFolder() async =>
      await getApplicationDocumentsDirectory();
}

AWS识别代码

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:intl/intl.dart';

import 'testb.dart';

class RekognitionHandler {
  final String _accessKey, _secretKey, _region;

  RekognitionHandler(this._accessKey, this._secretKey, this._region);

  Future<String> _rekognitionHttp(String amzTarget, String body) async {
    String endpoint = "https://rekognition.$_region.amazonaws.com/";
    String host = "rekognition.$_region.amazonaws.com";
    String httpMethod = "POST";
    String service = "rekognition";

    var now = new DateTime.now().toUtc();
    var amzFormatter = new DateFormat("yyyyMMdd'T'HHmmss'Z'");
    String amzDate =
    amzFormatter.format(now); // format should be '20170104T233405Z"

    var dateFormatter = new DateFormat('yyyyMMdd');
    String dateStamp = dateFormatter.format(
        now); // Date w/o time, used in credential scope. format should be "20170104"

    int bodyLength = body.length;

    String queryStringParamters = "";
    Map<String, String> headerParamters = {
      "content-length": bodyLength.toString(),
      "content-type": "application/x-amz-json-1.1",
      "host": host,
      "x-amz-date": amzDate,
      "x-amz-target": amzTarget
    };

    String signature = Signature.generateSignature(
        endpoint,
        service,
        _region,
        _secretKey,
        httpMethod,
        now,
        queryStringParamters,
        headerParamters,
        body);

    String authorization =
        "AWS4-HMAC-SHA256 Credential=$_accessKey/$dateStamp/$_region/$service/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target, Signature=$signature";
    headerParamters.putIfAbsent('Authorization', () => authorization);

    //String labelsArray = "";
    StringBuffer builder = new StringBuffer();
    try {
      HttpClient httpClient = new HttpClient();
      httpClient.connectionTimeout = Duration(minutes: 10);
      HttpClientRequest request = await httpClient.postUrl(Uri.parse(endpoint));

      request.headers.set('content-length', headerParamters['content-length']);
      request.headers.set('content-type', headerParamters['content-type']);
      request.headers.set('host', headerParamters['host']);
      request.headers.set('x-amz-date', headerParamters['x-amz-date']);
      request.headers.set('x-amz-target', headerParamters['x-amz-target']);
      request.headers.set('Authorization', headerParamters['Authorization']);

      request.write(body);

      HttpClientResponse response = await request.close();

      await for (String a in response.transform(utf8.decoder)) {
        builder.write(a);
      }
    } catch (e) {
      print(e);
    }

    return Future.value(builder.toString());
  }

  Future<String> compareFaces(
      File sourceImagefile, File targetImagefile) async {
    try {
      List<int> sourceImageBytes = sourceImagefile.readAsBytesSync();
      String base64SourceImage = base64Encode(sourceImageBytes);
      List<int> targetImageBytes = targetImagefile.readAsBytesSync();
      String base64TargetImage = base64Encode(targetImageBytes);
      String body =
          '{"SourceImage":{"Bytes": "$base64SourceImage"},"TargetImage":{"Bytes": "$base64TargetImage"}}';
      String amzTarget = "RekognitionService.CompareFaces";

      String response = await _rekognitionHttp(amzTarget, body);
      return response;
    } catch (e) {
      print(e);
      return "{}";
    }
  }
}

0 个答案:

没有答案