#java #javafx
#java #javafx
Вопрос:
В качестве части приложения для обработки изображений мне нужно создать простой модуль просмотра с функциями масштабирования, прокрутки и векторного наложения. Изображения довольно большие: ~ 40000×20000, что замедляет операции с ImageView, буферизует и т.д. Каковы наилучшие варианты улучшения пользовательского опыта при работе с огромными изображениями в JavaFX?
Комментарии:
1. Вы когда-нибудь выясняли, как сделать это производительным? Я пытаюсь поместить это изображение из синего мрамора в качестве фона и сталкиваюсь с аналогичными проблемами. Кэширование не помогает.
2. Я решил использовать реализацию плиточной панели, как здесь: gist.github.com/james-d/a249470377fb3c58784a9349a22641c4 Это многопоточность, и вы можете довольно легко реализовать кэш для этого решения. Конечно, вы должны использовать формат изображения, который поддерживает частичное чтение из определенного пикселя.
Ответ №1:
У меня есть изображение размером 8 на 4k, которое отлично масштабируется за счет кэширования области прокрутки, в которую я его поместил, и использования этого кода для масштабирования. Единственная проблема с панелью прокрутки и большими изображениями заключается в том, что панорамирование ужасно и медленно, для чего я пытаюсь найти решение в моем текущем приложении.
final double SCALE_DELTA = 1.175;
private double SCALE_TOTAL = 1;
.
//Adds functionality to scrolling
mapScroll.addEventFilter(ScrollEvent.ANY, e ->{
//Consumes the event
e.consume();
if(e.getDeltaY() == 0)
{
return;
}
double scaleFactor =
(e.getDeltaY() > 0)
? SCALE_DELTA
: 1/SCALE_DELTA;
//Ensures that you do not exceed the limits of the map
if(scaleFactor * SCALE_TOTAL >= 1)
{
Bounds viewPort = mapScroll.getViewportBounds();
Bounds contentSize = mapGrid.getBoundsInParent();
double centerPosX = (contentSize.getWidth() - viewPort.getWidth()) * mapScroll.getHvalue() viewPort.getWidth() / 2;
double centerPosY = (contentSize.getHeight() - viewPort.getHeight()) * mapScroll.getVvalue() viewPort.getHeight() / 2;
mapGrid.setScaleX(mapGrid.getScaleX() * scaleFactor);
mapGrid.setScaleY(mapGrid.getScaleY() * scaleFactor);
SCALE_TOTAL *= scaleFactor;
double newCenterX = centerPosX * scaleFactor;
double newCenterY = centerPosY * scaleFactor;
mapScroll.setHvalue((newCenterX - viewPort.getWidth()/2) / (contentSize.getWidth() * scaleFactor - viewPort.getWidth()));
mapScroll.setVvalue((newCenterY - viewPort.getHeight()/2) / (contentSize.getHeight() * scaleFactor -viewPort.getHeight()));
}
});