1

Hy fellow Flutter lovers!

Disclaimer: my code looks like a bomb site- that's because i'm relatively new to flutter.

import 'dart:convert';
import 'dart:typed_data';
import 'package:async/async.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:flutter_svprogresshud/flutter_svprogresshud.dart';
import 'package:photo_view/photo_view.dart';
import 'package:image/image.dart' as Imagi;

class DetailPage extends StatefulWidget {
  final BluetoothDevice server;

  const DetailPage({required this.server});

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

class _DetailPageState extends State<DetailPage> {
  
  BluetoothConnection? connection;
  bool isConnecting = true;
  bool morethan0 = false;

  bool get isConnected => connection != null && connection!.isConnected;
  bool isDisconnecting = false;

  late String _selectedFrameSize;

  List<List<int>> chunks = <List<int>>[];
  List<List<int>> imgArray = [];
  int contentLength = 0;
  Uint8List _bytes = new Uint8List(0);

  decode() {

    final decoder = Imagi.JpegDecoder();
    final decodedImg = decoder.decodeImage(_bytes);
    final decodedBytes = decodedImg!.getBytes(format: Imagi.Format.rgb);

    for(int x = 0; x < decodedImg.width; x++) {
      int red = decodedBytes[decodedImg.width*3 + x*3];
      int green = decodedBytes[decodedImg.width*3 + x*3 + 1];
      int blue = decodedBytes[decodedImg.width*3 + x*3 + 2];
      imgArray.add([red, green, blue]);
    }
    setState(() {
    });

    print(imgArray);
  }
  

  late RestartableTimer _timer;

  @override
  void initState() {
    super.initState();
    _selectedFrameSize = '0';
    _getBTConnection();
    _timer = new RestartableTimer(Duration(seconds: 3), _drawImage);
  }

  @override
  void dispose() {
    if (isConnected) {
      isDisconnecting = true;
      connection!.dispose();
      connection = null;
    }
    _timer.cancel();
    super.dispose();
  }

  _getBTConnection() {
    BluetoothConnection.toAddress(widget.server.address).then((_connection) {
      connection = _connection;
      isConnecting = false;
      isDisconnecting = false;
      setState(() {});
      connection!.input!.listen(_onDataReceived).onDone(() {
        if (isDisconnecting) {
          print('Disconnecting locally');
        } else {
          print('Disconnecting remotely');
        }
        if (this.mounted) {
          setState(() {});
        }
        Navigator.of(context).pop();
      });
    }).catchError((error) {
      Navigator.of(context).pop();
    });
  }

  _drawImage() {
    if (chunks.isEmpty || contentLength == 0) return;
    print(Image.memory(_bytes));

    _bytes = Uint8List(contentLength);
    int offset = 0;
    for (final List<int> chunk in chunks) {

      _bytes.setRange(offset, offset + chunk.length, chunk);
      offset += chunk.length;
    }

    setState(() {});

    contentLength = 0;
    chunks.clear();
    
  }

  void _onDataReceived(Uint8List data) {
    if (data.isNotEmpty) {
      chunks.add(data);
      contentLength += data.length;
      _timer.reset();
      morethan0 = true;
    }

    print("Data Length: ${data.length}, chunks: ${chunks.length}");
    
  }

  void _sendMessage(String text) async {
    text = text.trim();
    if (text.isNotEmpty) {
      try {
        List<int> list = text.codeUnits;
        Uint8List bytes = Uint8List.fromList(list);
        connection!.output.add(bytes);
        SVProgressHUD.show();
        await connection!.output.allSent;
      } catch (e) {
        setState(() {});
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: (isConnecting
              ? Text('Connecting to ${widget.server.name} ...')
              : isConnected
                  ? Text('Connected with ${widget.server.name}')
                  : Text('Disconnected with ${widget.server.name}')),
        ),
        body: SafeArea(
          child: isConnected
              ? Column(
                  children: <Widget>[
                    shotButton(),
                    photoFrame(),
                  ],
                )
              : Center(
                  child: Text(
                    "Connecting...",
                    style: TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                        color: Colors.white),
                  ),
                ),
        ));
  }

  Widget photoFrame() {
    return Expanded(
      child: Container(
        width: double.infinity,
        child: _bytes != null
            ? PhotoView(
                enableRotation: true,
                initialScale: PhotoViewComputedScale.covered,
                maxScale: PhotoViewComputedScale.covered * 2.0,
                minScale: PhotoViewComputedScale.contained * 0.8,
                imageProvider: Image.memory(_bytes, fit: BoxFit.fitWidth).image,
              )
            : Container(),
      ),
    );
  }

  Widget shotButton() {
    return Container(
      padding: const EdgeInsets.all(16),
      child: ElevatedButton(
        onPressed: () {
          _sendMessage(_selectedFrameSize);
          decode();
        },
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text(
            'TAKE A SHOT',
            style: TextStyle(fontSize: 24),
          ),
        ),
      ),
    );
  }
}

I am using bluetooth serial library to get data from arduino. It all works, devices connect, image is drawn every time i press the "take a shot" button. The problem arises when i try to get the RGB data from 1 pixel row of the image- when i call decode() function, it prints out the rgb data, but:

  • Data is always the same - the array gets full in the 1st run and it won't update from there, like the array is fixed somehow??? Picture changes of course, but data wont
  • I don't know how to select n-th row of pixels since i don't understand what chunks are

I really appreciate you looking into this, have a wonderful day!

0 Answers0