Мне нужно применить преобразование Matrix4 к моему изображению, завернутому в InteractiveViewer
. Изображения всегда имеют соотношение 3:4.
Он работает нормально на исходном устройстве, которое изменяет Matrix4 (панорамирование/масштабирование), проблема в том, что когда я отправляю значения Matrix4 на другое устройство (например, планшет), чтобы загрузить то же изображение и повторно использовать преобразование Matrix4, это не то же самое, поэтому я подозревал, что это может быть из-за размеров экрана.
Matrix4 отправляется как строковое сообщение с использованием String.fromCharCodes(matrix4.storage.buffer.asUint8List())
.
Я попробовал отправить значение масштаба и перевести смещение отдельно, чтобы использовать Transform.scale()
и Transform.translate()
, но это работает не очень хорошо.
Мой макет выглядит следующим образом:
Stack(
alignment: Alignment.bottomCenter,
children: [
AspectRatio(
aspectRatio: 9/16,
child: LayoutBuilder(
builder: (context, constraints) {
return ClipRect(
child: SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
child: InteractiveViewer(
transformationController: _controller,
child: Image.network('https://picsum.photos/seed/picsum/200/300'),
),
),
);
},
),
),
],
);
Мой вопрос: как я могу повторно использовать одно и то же преобразование Matrix4 для получения одного и того же результата независимо от устройств и размеров экрана?
Поэтому, когда я масштабирую/панорамирую изображение, я не знаю, как масштабировать матрицу перед отправкой и как уменьшить ее в зависимости от размеров экрана другого устройства. Достижимо ли это с помощью матрицы4?
Большое спасибо за направление, к сожалению, у меня пока ничего не получилось, у меня проблемы с масштабным коэффициентом, позвонив getMaxScaleOnAxis
, у вас уже есть последняя шкала, примененная к InteractiveViewer
, зачем нам нужно умножать ее на коэффициент (0,3 в вашем образец) на удаленной стороне? Когда я попытался изменить ваш образец, чтобы использовать масштабный коэффициент, полученный из InteractiveViewer.onInteractionUpdate
(scale*ScaleUpdateDetails.scale), результат был другим.
Вот демо-версия моего телефона и планшета: ссылка
0.3
был просто примерным фактором, проверьте мою обновленную суть: теперь это больше похоже на ваш случай AspectRatio
9:16 - масштаб такой: scale: scale * remoteSize.width / localSize.width
я сделал это немного проще: теперь localSize.width
не нужен на удаленной стороне (это часть scale
), также вычисление матрицы теперь стало проще, проверьте мою окончательную суть
Что-то не так, на этот раз я точно следую вашей сути: при увеличении масштаба на локальной стороне фотография на удаленной стороне уменьшается до крошечной точки. Я попробовал запустить пример кода из вашей сути на телефоне и планшете, используя жестко запрограммированное значение, результат также неудовлетворительный.
Спасибо за продолжение, теперь я вижу, единственная разница заключалась в том, что мой InteractiveViewer
был constrained: true
вместо неограниченного. Когда я превратил его в ложное, оно РАБОТАЕТ отлично. Это в основном отвечает на мой вопрос, но неограниченное изображение изначально слишком сильно увеличено, и, поскольку начального свойства масштаба нет, я думаю, мне придется проделать некоторые трюки. Спасибо, чувак, ты спасаешь жизни. Не могли бы вы опубликовать свое решение выше как отдельный ответ, чтобы я мог его принять!
«и поскольку нет свойства начального масштаба» - тогда используйте transformationController: _controller
, который изначально масштабируется, и если хотите, не стесняйтесь опубликовать собственный ответ
@pskink Не хочу вас снова беспокоить, похоже, у InteractiveViewer
есть немало проблем, связанных с начальным масштабом, происходящим здесь github. Итак, я попытался вернуться к constrained: true
, получить смещениеX и смещениеY из локальной матрицы, разделить их на localSize.width
и localSize.height
и отправить их вместо привязки, на удаленной стороне я получаю, умножая их на remoteSize.width
и remoteSize.height
, но пока безуспешно. Как вы думаете, это можно сделать с помощью constrained: true
?
«Как вы думаете, это можно сделать с помощью constrained: true?» - я так не думаю, с constrained: true
довольно сложно контролировать, как рисуется ребенок, а если constrained: false
вы можете полностью контролировать это, то в чем проблема с вычислением начального значения TranformationController
? вы не знаете размер ребенка (вашего изображения)?
Я знаю размер моего изображения, проблема снова в размерах экрана: такие устройства, как планшет, могут отображать все изображение целиком, тогда как телефоны должны уменьшаться, чтобы соответствовать размеру constrained: true
, в таких случаях местоположение больше не является точным. Например: когда я размещаю маркер. Если я просто применю начальную шкалу на всех устройствах, то на некоторых будет так: ссылка. Итак, я думаю, что если я смогу извлечь смещение из матрицы и сопоставить его с локальной позицией, возможно, я смогу синхронизироваться с удаленной стороной (например, когда я применяю касание для масштабирования определенной области). Но надежды пока нет.
Если у вас есть размер интерактивного средства просмотра (поскольку вы используете конструктор макетов) и размер изображения, то рассчитать исходную матрицу легко: gist.github.com/pskink/6ef88df64d7764fd0efcd60aa618f0c0
Вот и все, похоже, я все-таки выберу constrained: false
. Большое спасибо за ваши указания, вы действительно спасли мне день.
Я обязательно это проверю, спасибо, приятель
Вся заслуга принадлежит @pskink
Проблема в том, что я не могу повторно использовать матрицу 4 напрямую на экранах разных размеров и ожидать того же результата, что и на локальном устройстве, но мне приходится масштабировать ее перед отправкой.
С локальной стороны получите масштаб и смещение привязки, как показано ниже:
final scale = _controller.getMaxScaleOnAxis() / localSize.width;
final anchor = _controller.toScene(Offset.zero);
А на удаленной стороне примените масштаб и перевод:
_remoteController.value = Matrix4.identity()
..scale(scale * remoteSize.width)
..translate(-anchor.dx, -anchor.dy);
localSize
и remoteSize
можно получить из LayoutBuilder
, например:
Size(constraints.maxWidth, constraints.maxHeight)
Примечание. Вышеупомянутое работает только при наличии InteractiveViewer
constrained: false
. Если вы хотите масштабировать исходную матрицу изображения, вы можете перейти по этой теме: github
@pskink Извините за неясность, изображения всегда имеют соотношение 3:4, а страница представляет собой виджет
AspectRatio
с соотношением сторон 9:16. Я могу определить положение события касания, чтобы увеличить изображение в точном месте на каждом устройстве, отправив смещение, например (dx/constraints.maxWidth)(dy/constraints.maxHeight), и получить его на другом устройстве, например (constraints.maxWidth * dx)(constraints.maxHeight * dy), используя метод из ссылки .