Swing: лучший способ реализовать функцию масштабирования в компоненте изображения - PullRequest
2 голосов
/ 27 августа 2011

Я создал SWING-компонент JImageEditor, который просто отображает картинку. Идея состоит в том, чтобы добавить больше функциональности к компоненту в будущем.

Одна функция, которую я уже реализовал, - это масштабирование. Прямо сейчас об этой части заботятся в методе paintComponent (). Тем не менее, я почему-то подозреваю, что это может быть плохой идеей, поскольку это означает, что изображение будет масштабироваться от исходного размера до текущего «масштаба» каждый раз, когда вызывается paintComponent (). Код paintComponent выглядит следующим образом:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
            RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    int w = getWidth();
    int h = getHeight();
    double imageWidth = scale * image.getWidth();
    double imageHeight = scale * image.getHeight();
    double x = (w - imageWidth) / 2;
    double y = (h - imageHeight) / 2;
    AffineTransform at = AffineTransform.getTranslateInstance(x, y);
    at.scale(scale, scale);
    g2.drawRenderedImage(image, at);
}

Теперь, в качестве альтернативы, я должен был сохранить два экземпляра BufferedImage, где один является оригиналом, а другой - текущим «представлением». Таким образом, я мог бы обрабатывать фактическое масштабирование / масштабирование всякий раз, когда вызывается метод setScale (), вместо масштабирования в paintComponent (). Однако недостатком является то, что мне нужно сохранить два экземпляра BufferedImage, что приведет к увеличению потребления памяти в зависимости от размера изображения. Конечно, невозможно предсказать, насколько большие изображения откроет любой данный пользователь с помощью компонента.

То, что я ищу, это либо большие пальцы вверх, если я на правильном пути с моей работой, либо большие пальцы вниз, если это плохой дизайн и какое-то другое решение должно быть рассмотрено. Я ценю весь вклад и вознагражу за все ответы, которые меня просвещают: -)

1 Ответ

3 голосов
/ 27 августа 2011

Я бы сказал, поместите секцию синхронизации в ваш компонент краски, чтобы измерить, сколько времени это займет.Получите вашу базовую меру от того, что у вас есть сейчас.Затем реализуйте оптимизированный метод с дополнительным BufferedImage.Сравните измерения и выберите тот, который меньше.У меня есть ощущение, что ваша интуиция верна, что аффинное преобразование каждый цикл рисования происходит медленно, и благодаря созданию двойного буфера для масштабированного изображения и источника будет быстрее.Хотя я не могу найти там ничего, что могло бы подтвердить или опровергнуть это, и на это могло бы повлиять аппаратное ускорение.

Если вы извлекли этот фрагмент кода в класс ZoomableBufferedImage, вы могли бы легко включить или выключитьоптимизированные / неоптимизированные версии.ZoomableBufferedImage будет содержать ссылку на исходное изображение и содержать дополнительное буферизованное изображение, в котором он может сохранить масштабированную версию. При увеличении / уменьшении ZoomableBufferedImage рисует в буфер или не на основе его настроек, затем в его метод рисованияон может рисовать либо из буфера, либо применяя AffineTransform к источнику и рисуя его в соответствии с его настройками.

...