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
Best Practices For Catching and Re-Throwing .Net Exceptions
Creating a Datetime in a Specific Time Zone in C#
How to Use Reflection to Invoke a Private Method
Given a Filesystem Path, Is There a Shorter Way to Extract the Filename Without Its Extension
How to Cast Object of Type 'System.Dbnull' to Type 'System.String'
Visual Studio Publish Project into One Simple Installer
What's the Difference Between the 'Ref' and 'Out' Keywords
Show/Hide the Console Window of a C# Console Application
How to Add a New Row to Datagridview Programmatically
Random.Next Returns Always the Same Values
Await on a Completed Task Same as Task.Result
Json.Net Serialize/Deserialize Derived Types
Finding Holes in 2D Point Sets
Suspending Event Not Raising Using Winrt