Swing/ZoomingAndPanning の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/ZoomingAndPanning へ行く。
- Swing/ZoomingAndPanning の差分を削除
--- category: swing folder: ZoomingAndPanning title: JPanelに表示した画像のズームとスクロール tags: [AffineTransform, Graphics, JPanel, MouseListener, MouseMotionListener, MouseWheelListener] author: aterai pubdate: 2014-04-21T00:28:49+09:00 description: JPanelに表示した画像にAffineTransformによる変換を適用して、マウスを使った拡大・縮小・移動を実行します。 image: https://lh3.googleusercontent.com/-c5Y9hCoRQbU/U1PhhnitgFI/AAAAAAAACD0/ZXIcyPywcr0/s800/ZoomingAndPanning.png --- * 概要 [#summary] `JPanel`に表示した画像に`AffineTransform`による変換を適用して、マウスを使った拡大・縮小・移動を実行します。[https://community.oracle.com/thread/1263955 How to implement Zoom & Pan in Java using Graphics2D]に投稿されているコードを参考・引用しています。 `JPanel`に表示した画像に`AffineTransform`による変換を適用して、マウスを使った拡大・縮小・移動を実行します。 #download(https://lh3.googleusercontent.com/-c5Y9hCoRQbU/U1PhhnitgFI/AAAAAAAACD0/ZXIcyPywcr0/s800/ZoomingAndPanning.png) * サンプルコード [#sourcecode] #code(link){{ class ZoomAndPanHandler extends MouseAdapter { private static final double ZOOM_FACTOR = 1.2; private static final int MIN_ZOOM = -10; private static final int MAX_ZOOM = 10; private static final int EXTENT = 1; private final BoundedRangeModel zoomRange = new DefaultBoundedRangeModel( 0, EXTENT, MIN_ZOOM, MAX_ZOOM + EXTENT); private final AffineTransform coordAndZoomAtf = new AffineTransform(); private final Point2D dragStartPoint = new Point(); @Override public void mousePressed(MouseEvent e) { dragStartPoint.setLocation(e.getPoint()); } @Override public void mouseDragged(MouseEvent e) { Point2D dragEndPoint = e.getPoint(); Point2D dragStart = transformPoint(dragStartPoint); Point2D dragEnd = transformPoint(dragEndPoint); coordAndZoomAtf.translate( dragEnd.getX() - dragStart.getX(), dragEnd.getY() - dragStart.getY()); dragStartPoint.setLocation(dragEndPoint); e.getComponent().repaint(); } @Override public void mouseWheelMoved(MouseWheelEvent e) { int dir = e.getWheelRotation(); int z = zoomRange.getValue(); zoomRange.setValue(z + EXTENT * (dir > 0 ? -1 : 1)); if (z != zoomRange.getValue()) { double scale = dir > 0 ? 1d / ZOOM_FACTOR : ZOOM_FACTOR; Point2D pt; if (e.isControlDown()) { Rectangle r = e.getComponent().getBounds(); pt = new Point2D.Double(r.getCenterX(), r.getCenterY()); } else { pt = transformPoint(e.getPoint()); } coordAndZoomAtf.translate(pt.getX(), pt.getY()); coordAndZoomAtf.scale(scale, scale); coordAndZoomAtf.translate(-pt.getX(), -pt.getY()); e.getComponent().repaint(); } } // https://community.oracle.com/thread/1263955 // How to implement Zoom & Pan in Java using Graphics2D private Point2D transformPoint(Point2D p1) { AffineTransform inverse = coordAndZoomAtf; boolean hasInverse = coordAndZoomAtf.getDeterminant() != 0d; if (hasInverse) { try { inverse = coordAndZoomAtf.createInverse(); } catch (NoninvertibleTransformException ex) { // should never happen assert false; } } Point2D p2 = new Point(); inverse.transform(p1, p2); return p2; } public AffineTransform getCoordAndZoomTransform() { return coordAndZoomAtf; } } }} * 解説 [#explanation] `AffineTransform#createInverse()`で取得した`AffineTransform`オブジェクトでマウス位置の逆変換を行い、現在表示されている倍率でのズームの中心や移動距離などを計算しています。 - ズーム -- ホイール上回転で拡大 -- ホイール下回転で縮小 - スクロール -- マウスドラッグで移動 * 参考リンク [#reference] - [https://community.oracle.com/thread/1263955 How to implement Zoom & Pan in Java using Graphics2D] - [http://codezine.jp/article/detail/174 ズームとパンの機能を備えたドローソフトを作成する:CodeZine] - [http://sozai-free.com/ 2000ピクセル以上のフリー写真素材集] - [http://tech.nitoyon.com/ja/blog/2013/12/13/touch-viewer/ タッチ操作に対応した画像ビューワーをJavaScriptで作るならD3.jsが便利 - てっく煮ブログ] - [https://torutk.hatenablog.jp/entry/20140415/p1 CanvasでAffine変換で大いにはまる(数学的センスが足りなかった・・・) - torutkのブログ] - [[JScrollPane内に配置したJPanelをマウスで拡大、縮小、移動する>Swing/ZoomAndPanPanel]] - [https://medium.com/@benjamin.botto/zooming-at-the-mouse-coordinates-with-affine-transformations-86e7312fd50b Zooming at the Mouse Coordinates with Affine Transformations | by Ben Botto | Medium] * コメント [#comment] #comment - 表示画面の中心を基準に拡大縮小するように変更。 -- &user(aterai); &new{2014-04-21 (月) 14:55:12}; - KBD{Ctrl}キーを押しながらホイールスクロールで表示画面の中心、それ以外はマウスカーソルを基準に拡大縮小するように変更。 -- &user(aterai); &new{2022-12-31 (土) 21:05:12}; #comment