Search
Write a publication
Pull to refresh
7
0

Разработчик мобильных приложений Flutter

Send message

Но возникает вопрос - как в таких приложениях генерирует сотни раскрасок? Вручную рисуют или же есть какой алгоритм?

Для генерации раскрасок, на мой взгляд, без ИИ не обойтись, если речь идет о сотнях изображений в кратчайшие сроки:

  • Можно воспользоваться DALL-E, либо GPT4, у которого можно тут же попросить написать код этого изображения в векторе, а также алгоритм на python для перевода изображения в вектор

  • Можно воспользоваться бесплатным Leonardo AI

  • Есть платные сервисы на основе ИИ, которые по промпту сразу генерируют SVG: https://illustroke.com/ (я не пользовался)

Есть также различные бесплатные сервисы по переводу растровых изображений в вектор, например, https://vectorizer.ai/, https://vectorization.eu/color-svg-converter/

Я честно говоря делал не точно такие (обрезку руками не реализовывал), но похожие с точки зрения требований (отрисовка произвольных фигур и paths), и не до конца понял зачем вам нужны матрицы? Ну т.е. тема интересная, я бы с удовольствием сам бы почитал, но разве у flutter нет методов translate и scale которые это могут под капотом сделать?

Матрицы, если в них +- разобраться, то будут проще в понимании при реализации простых преобразований. У flutter есть также виджеты Transform.scale() и Transform.translate(), и при желании можно воспользоваться ими без необходимости воздействовать напрямую на матрицу

Прямоугольник кстати прям на канвасе рисовать можно, не знаю как в flutter, но в compose есть drawWithContent, где можно нарисовать что-то своё поверх (или за) контентом. Во flutter тоже что-то похожее должно быть точно.

Да, можно и так

Да, во flutter есть реализованные методы для трансформаций матриц, например: трансляция, масштабирование.

Согласитесь, что выглядит сложновато для понимания + если напрямую использовать трансляцию вместе с масштабированием, к примеру, вот так:

  void _onScaleUpdate(ScaleUpdateDetails details) {
    Matrix4 matrix = _matrix;

    final newFocalPoint = details.focalPoint;
    final offsetDelta = (newFocalPoint - _focalPoint);
    _focalPoint = newFocalPoint;
    matrix = matrix.clone()..translate(offsetDelta.dx, offsetDelta.dy);

    final newScale = details.scale;
    if (newScale != 1.0) {
      final scaleDelta = newScale / _scale;
      _scale = newScale;
      matrix = matrix.clone()..scale(scaleDelta, scaleDelta);
    }

    setState(() {
      _matrix = matrix;
    });
  }

То может получиться вот такой результат:

Поэтому мне было проще и понятнее реализовать только те трансформации, которые мне требуются для этой задачи, чем вносить поправки при использовании существующих методов.

  • У Image нужно вызывать dispose, иначе она будет вечно в памяти

Не знал про наличие этого метода у image, спасибо, что подсказали.

  • Минус вашего подхода - потеря оригинала изображение (в следствии рисования его на канвасе) - что ведёт к ситуации, когда вырезанный фрагмент в вашем приложении не такой же, как если бы я вырезал его инструментом, предназначенным для этого

Все верно, манипуляции проводятся не с оригиналом. В следующих статьях я рассмотрю, каким образом можно избежать как минимум потери разрешения.

Спасибо за рекомендацию, ранее не обращал внимания на этот параметр. Сейчас попробовал, действительно, выглядит как хорошая идея

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

В данном случае я не рассматриваю этот вариант, т.к. в итоге пришел к другому решению, которое описал во второй части статьи

Пока я планирую реализовать только различные варианты кистей для рисования, для этого вполне хватает тех возможностей, которые предоставляет Flutter

Да, вы правы, что в данном примере использование шейдера не влияет на производительность напрямую. Также сам код шейдера из примера не дает разницы в качестве по сравнению с отрисовкой с помощью метода drawImage() в CustomPainter. Картинка такая же пиксельная, и с виду немного хуже, чем при использовании Image.memory().

Но само использование шейдера дает больше возможностей. Результат можно улучшить, например, добавив в код шейдера антиалиасинг, чтобы появился эффект сглаживания и картинка казалась менее пиксельной. В статье дополнил реализацию шейдера.

Таким образом, шейдер здесь уже как бы для закрепления полученного результата. Иначе из-за потери качества пришлось бы откатить к варианту преобразования в байты и дальнейшей отрисовки через Image.memory(), а это шаг назад в плане производительности.

Information

Rating
Does not participate
Location
Porto, Porto, Португалия
Date of birth
Registered
Activity

Specialization

Mobile Application Developer, Application Developer
Senior
From 450,000 ₽
Flutter
Dart
Development of mobile applications
Android development
iOS development
Client-server applications