Как преобразовать Flutter CameraImage в объект двоичных данных в кодировке Base64 из потока изображений - PullRequest
0 голосов
/ 17 января 2019

С появлением потока изображений в флаттер-камере версии 0.2.8 я попытался интегрировать его в свой проект для использования вместе с AWS.

Амазону требуется изображение в формате:

  • Блок байтов изображения размером до 5 МБ.
  • Тип: объект двоичных данных в кодировке Base64
  • Ограничения длины: минимальная длина 1. Максимальная длина 5242880.
<Ч />

Ранее я использовал пакет Camera, чтобы сделать снимок, загрузить изображение, а затем преобразовать его в соответствии с требованиями amazon, но использование ImageStream намного больше подходит для того, что я хотел бы сделать. Мой предыдущий подход был:

// Take the picutre
await _cameraController.takePicture(path);

// Load it from my filesystem
File imagefile = new File(path); 

// Convert to amazon requirements
List<int> imageBytes = imagefile.readAsBytesSync();
String base64Image = base64Encode(imageBytes);

Однако, используя поток изображений, я не могу найти простой способ конвертировать CameraImage в формат, который требуется amazon. У меня нет большого опыта с изображениями, поэтому я застрял.

Я попытался манипулировать кодом, используемым в демонстрационной программе firebase ml & camera stream

final int numBytes =
    image.planes.fold(0, (count, plane) => count += plane.bytes.length);
final Uint8List allBytes = Uint8List(numBytes);

int nextIndex = 0;
for (int i = 0; i < image.planes.length; i++) {
  allBytes.setRange(nextIndex, nextIndex + image.planes[i].bytes.length,
      image.planes[i].bytes);
  nextIndex += image.planes[i].bytes.length;
}

// Convert as done previously
String base64Image = base64Encode(allBytes);

Однако AWS ответил InvalidImageFormatException. Если кто-то знает, как правильно кодировать изображение, это было бы здорово! Спасибо

1 Ответ

0 голосов
/ 13 июня 2019

Решение для преобразования изображения в png:

Future<Image> convertYUV420toImageColor(CameraImage image) async {
  try {
    final int width = image.width;
    final int height = image.height;
    final int uvRowStride = image.planes[1].bytesPerRow;
    final int uvPixelStride = image.planes[1].bytesPerPixel;

    print("uvRowStride: " + uvRowStride.toString());
    print("uvPixelStride: " + uvPixelStride.toString());

    // imgLib -> Image package from https://pub.dartlang.org/packages/image
    var img = imglib.Image(width, height); // Create Image buffer

    // Fill image buffer with plane[0] from YUV420_888
    for(int x=0; x < width; x++) {
      for(int y=0; y < height; y++) {
        final int uvIndex = uvPixelStride * (x/2).floor() + uvRowStride*(y/2).floor();
        final int index = y * width + x;

        final yp = image.planes[0].bytes[index];
        final up = image.planes[1].bytes[uvIndex];
        final vp = image.planes[2].bytes[uvIndex];
        // Calculate pixel color
        int r = (yp + vp * 1436 / 1024 - 179).round().clamp(0, 255);
        int g = (yp - up * 46549 / 131072 + 44 -vp * 93604 / 131072 + 91).round().clamp(0, 255);
        int b = (yp + up * 1814 / 1024 - 227).round().clamp(0, 255);     
        // color: 0x FF  FF  FF  FF 
        //           A   B   G   R
        img.data[index] = (0xFF << 24) | (b << 16) | (g << 8) | r;
      }
    }

    imglib.PngEncoder pngEncoder = new imglib.PngEncoder(level: 0, filter: 0);
    List<int> png = pngEncoder.encodeImage(img);
    muteYUVProcessing = false;
    return Image.memory(png);  
  } catch (e) {
    print(">>>>>>>>>>>> ERROR:" + e.toString());
  }
  return null;
}

Источник: https://github.com/flutter/flutter/issues/26348#issuecomment-462321428

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...