Pan & Zoom Image

Pan & Zoom Image

The way I solved this problem was to place the image within a Border with it's ClipToBounds property set to True. The RenderTransformOrigin on the image is then set to 0.5,0.5 so the image will start zooming on the center of the image. The RenderTransform is also set to a TransformGroup containing a ScaleTransform and a TranslateTransform.

I then handled the MouseWheel event on the image to implement zooming

private void image_MouseWheel(object sender, MouseWheelEventArgs e)
{
var st = (ScaleTransform)image.RenderTransform;
double zoom = e.Delta > 0 ? .2 : -.2;
st.ScaleX += zoom;
st.ScaleY += zoom;
}

To handle the panning the first thing I did was to handle the MouseLeftButtonDown event on the image, to capture the mouse and to record it's location, I also store the current value of the TranslateTransform, this what is updated to implement panning.

Point start;
Point origin;
private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
image.CaptureMouse();
var tt = (TranslateTransform)((TransformGroup)image.RenderTransform)
.Children.First(tr => tr is TranslateTransform);
start = e.GetPosition(border);
origin = new Point(tt.X, tt.Y);
}

Then I handled the MouseMove event to update the TranslateTransform.

private void image_MouseMove(object sender, MouseEventArgs e)
{
if (image.IsMouseCaptured)
{
var tt = (TranslateTransform)((TransformGroup)image.RenderTransform)
.Children.First(tr => tr is TranslateTransform);
Vector v = start - e.GetPosition(border);
tt.X = origin.X - v.X;
tt.Y = origin.Y - v.Y;
}
}

Finally don't forget to release the mouse capture.

private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
image.ReleaseMouseCapture();
}

As for the selection handles for resizing this can be accomplished using an adorner, check out this article for more information.

Pan and Zoom Image Plugin

Follow this:

1- To install this library, run:

npm install iv-viewer
npm install ng2-image-viewer

2- in AppModule

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

// Import your library
import { ImageViewerModule } from 'ng2-image-viewer';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,

// Specify your library as an import
ImageViewerModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

3- Now just add the these codes on your angular-cli.json file:

"styles": [
"../node_modules/ng2-image-viewer/imageviewer.scss"
],

4- Once your library is imported, you can use its components, directives and pipes in your Angular application:

<!-- You can now use your library component in app.component.html -->
<h1>
Image Viewer
</h1>
<app-image-viewer [images]="['https://picsum.photos/900/500/?random', 'https://picsum.photos/900/500/?random', 'https://picsum.photos/900/500/?random']"
[idContainer]="'idOnHTML'"
[loadOnInit]="true"></app-image-viewer>

DEMO

How do I pan and zoom an image?

I'm not sure what you mean by "doesn't work" but you're on the right track.

Check out https://github.com/flutter/flutter/blob/master/examples/layers/widgets/gestures.dart for a working example of a widget you can pan, pinch, and scale.

Java : How to do image manipulation (pan, zoom, flip and rotate)?

Here is a simple program that demonstrates what I suggested, namely a large image set as the icon of a JLabel and the JLabel is the scrollable client for a JScrollPane. Note that I set the preferred size of the JScrollPane to 800 x 600 pixels because the default behavior is to make the JScrollPane the same size as its scrollable client. The image dimensions are 2312 x 1536 pixels which means it is larger than my computer screen. So if I don't set the preferred size, when you run the program the JFrame overflows the screen. You don't see all of the JFrame. This is on purpose so you can see how the image scrolls. The URL for the image is https://unsplash.com/photos/l68Z6eF2peA. And here is the code, which is a MCVE

By the way, I downloaded and saved the image in a file that I named worldmap.jpg

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;

public class ScrolImg implements Runnable {
private JFrame frame;
/* Start 'Runnable' interface methods. */
public void run() {
showGui();
}
/* End 'Runnable' interface methods. */
private JScrollPane createMainPanel() {
Icon ico = new ImageIcon("worldmap.jpg");
JLabel label = new JLabel(ico);
JScrollPane scrollPane = new JScrollPane(label);
scrollPane.setPreferredSize(new Dimension(800, 600));
return scrollPane;
}

private void showGui() {
frame = new JFrame("ScrolImg");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
ScrolImg instance = new ScrolImg();
EventQueue.invokeLater(instance);
}
}

Hopefully this code will help you complete your project.

Pan and zoom, but contain image inside parent container

Try the code below, does it make sense for you.

    private void MainImage_MouseMove(object sender, MouseEventArgs e)
{
// Don't drag when full scale and don't drag it if mouse not held down on image
if (!MainImage.IsMouseCaptured || scaleTransform.ScaleX == 1)
{
return;
}

// Drag image by modifying X,Y coordinates
var dragMousePosition = start - e.GetPosition(this);

var newXproperty = origin.X - dragMousePosition.X;
var newYproperty = origin.Y - dragMousePosition.Y;

var isXOutOfBorder = this.MainBorderImage.ActualWidth < (this.MainImage.ActualWidth * this.scaleTransform.ScaleX);
var isYOutOfBorder = this.MainBorderImage.ActualHeight < (this.MainImage.ActualHeight * this.scaleTransform.ScaleY);
if ((isXOutOfBorder && newXproperty> 0) || (!isXOutOfBorder && newXproperty < 0))
{
newXproperty = 0;
}
if((isYOutOfBorder && newYproperty > 0) || (!isYOutOfBorder && newYproperty < 0))
{
newYproperty = 0;
}
var maxX = this.MainBorderImage.ActualWidth - (this.MainImage.ActualWidth * this.scaleTransform.ScaleX);
if ((isXOutOfBorder && newXproperty < maxX) || (!isXOutOfBorder && newXproperty > maxX))
{
newXproperty = maxX;
}
var maxY = this.MainBorderImage.ActualHeight - (this.MainImage.ActualHeight * this.scaleTransform.ScaleY);
if ((isXOutOfBorder && newYproperty < maxY) || (!isXOutOfBorder && newYproperty > maxY))
{
newYproperty = maxY;
}

translateTransform.X = newXproperty;
translateTransform.Y = newYproperty;

e.Handled = true;
}

How to implement zoom and pan on an Image in jetpack compose

There is currently not possible to do that with compose.

However i recommend you to interop with TouchImageView or similiar using AndroidView composable.

How to Zoom and Pan Image in Python?

You should convert canvas coordinates to image coordinates during processing the image itself.

For example, for to the code "Move and zoom a tkinter canvas with mouse" add the following event to the __init__ method of the Zoom class:

self.canvas.bind('<ButtonPress-3>', self.get_coords)  # get coords of the image

Function self.get_coords convert coordinates of right mouse button click event to the image coordinates and print them on console:

def get_coords(self, event):
""" Get coordinates of the mouse click event on the image """
x1 = self.canvas.canvasx(event.x) # get coordinates of the event on the canvas
y1 = self.canvas.canvasy(event.y)
xy = self.canvas.coords(self.imageid) # get coords of image's upper left corner
x2 = round((x1 - xy[0]) / self.imscale) # get real (x,y) on the image without zoom
y2 = round((y1 - xy[1]) / self.imscale)
if 0 <= x2 <= self.image.size[0] and 0 <= y2 <= self.image.size[1]:
print(x2, y2)
else:
print('Outside of the image')

Also I advise you to use more anvanded zoom technique from here. Especially the 2nd code example after bold EDIT text.

( panzoom ) How to stop Image from panning out of the view?

It seems there is bounds property





const element = document.querySelector('#scene');


const zoomLevels = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3];

let currentZoomLevel = zoomLevels[4];

const text = document.querySelector('#text');


let panZoomController = panzoom(element, {

bounds: true,

boundsPadding: 0.1

});
div {

overflow: hidden;

border: 3px solid red

}


img {

cursor: move;

}
<script src="https://unpkg.com/panzoom@8.1.0/dist/panzoom.min.js"></script>


<body>

<div>

<img id="scene" src="https://www.probytes.net/wp-content/uploads/2018/01/5-1.png">

</div>


<br/>

<span>Image should not be Dragged /panned out of the view</span>

</body>


Related Topics



Leave a reply



Submit