Swing/ZoomingAndPanning のバックアップソース(No.12)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/ZoomingAndPanning へ行く。
- 1 (2014-04-21 (月) 00:28:49)
- 2 (2014-04-21 (月) 14:42:00)
- 3 (2014-04-23 (水) 17:23:05)
- 4 (2014-08-29 (金) 00:30:12)
- 5 (2014-11-25 (火) 03:03:31)
- 6 (2015-11-25 (水) 21:21:19)
- 7 (2016-01-27 (水) 15:22:41)
- 8 (2017-06-27 (火) 13:56:33)
- 9 (2018-06-07 (木) 18:15:10)
- 10 (2020-06-02 (火) 19:04:26)
- 11 (2021-11-19 (金) 00:41:10)
- 12 (2022-08-05 (金) 16:00:52)
- 13 (2022-12-31 (土) 20:52:14)
--- 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]に投稿されているコードを参考・引用しています。 #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()) { return; } Component c = e.getComponent(); Rectangle r = c.getBounds(); Point2D p = new Point2D.Double(r.getCenterX(), r.getCenterY()); Point2D p1 = transformPoint(p); double scale = dir > 0 ? 1 / ZOOM_FACTOR : ZOOM_FACTOR; coordAndZoomAtf.scale(scale, scale); Point2D p2 = transformPoint(p); coordAndZoomAtf.translate(p2.getX() - p1.getX(), p2.getY() - p1.getY()); c.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が便利 - てっく煮ブログ] - [http://d.hatena.ne.jp/torutk/20140415/p1 CanvasでAffine変換で大いにはまる(数学的センスが足りなかった・・・) - torutkの日記] - [[JScrollPane内に配置したJPanelをマウスで拡大、縮小、移動する>Swing/ZoomAndPanPanel]] * コメント [#comment] #comment - 表示画面の中心を 基準に拡大縮小するように変更。 -- &user(aterai); &new{2014-04-21 (月) 14:55:12}; #comment