Добавление водяного знака изображения в мобильное приложение Flutter - PullRequest
0 голосов
/ 13 апреля 2020

Я просматривал примеры пакетов с изображениями . Пример, приведенный для рисования изображения, использует пакет dart: html.

Мне удалось заставить что-то работать с комбинацией изображения и дротика: интерфейс, но он работает очень медленно. Кто-нибудь знает, что может быть лучше go об этом?

      final double canvasWidth = canvasImage.width.toDouble();
      final double canvasHeight = canvasImage.height.toDouble();
      final ui.Paint paint = ui.Paint();

      final recorder = ui.PictureRecorder();
      final canvas = ui.Canvas(
        recorder,
        ui.Rect.fromPoints(
          ui.Offset(0.0, 0.0),
          ui.Offset(canvasWidth, canvasHeight),
        ),
      );

      // draw image to background
      ui.Codec backgroundCodec =
          await ui.instantiateImageCodec(img.encodePng(canvasImage));
      final ui.FrameInfo backgroundFrameInfo =
          await backgroundCodec.getNextFrame();
      final ui.Image backgroundImage = backgroundFrameInfo.image;
      canvas.drawImage(backgroundImage, ui.Offset(0.0, 0.0), paint);

      // Add watermark
      // Get watermark from assets
      final ByteData watermarkBytes =
          await rootBundle.load("images/watermark.png");
      img.Image originalWatermark =
          img.decodeImage(watermarkBytes.buffer.asUint8List());

      // resize the watermark to 1/6th of the smallest dimension (the watermark is a square)
      final int watermarkDimension =
          (min(canvasWidth, canvasHeight) / 6).floor();
      img.Image resizeImage = img.copyResize(originalWatermark,
          height: watermarkDimension, width: watermarkDimension);
      ui.Codec watermarkCodec =
          await ui.instantiateImageCodec(img.encodePng(resizeImage));
      final ui.FrameInfo watermarkFrameInfo =
          await watermarkCodec.getNextFrame();

      // get ui image
      ui.Image watermarkImage = watermarkFrameInfo.image;

      // draw watermark to the canvas
      canvas.drawImage(watermarkImage, ui.Offset(0.0, 0.0), paint);

      // export the recording
      ui.Picture pic = recorder.endRecording();
      ui.Image finalImage =
          await pic.toImage(canvasWidth.floor(), canvasHeight.floor());
      ByteData finalByteData =
          await finalImage.toByteData(format: ui.ImageByteFormat.png);

1 Ответ

0 голосов
/ 13 апреля 2020

Я столкнулся с тем, что использование библиотеки изображений довольно медленное. В качестве альтернативы я использую RepaintBoundary для скриншота определенного виджета:

оборачиваем ваш виджет внутри RepaintBoundary с помощью ключа

RepaintBoundary(
              key: _repaintKey,
              child: Stack(
                alignment: Alignment.bottomRight,
                children: <Widget>[
                  Image.asset(
                    'images/food01.jpeg',
                    fit: BoxFit.cover,
                  ),
                  Icon(Icons.translate,),
                ],
              ),
            )

а затем записать байты:

    RenderRepaintBoundary boundary =
                    _repaintKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
File(tempPath).writeAsBytes(pngBytes);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...