Image manipulations in Universal Windows app - c#

I have an image element inside a grid along with other controls in it. I want to be able to zoom the image. I don't want to place it inside a scroll viewer as I don't know the dimensions of the image and as it is a Universal app, I am having a lot of Adpative UI and the ScrollViewer messes with whole thing. The Image is downloaded from the web. When the user swipes left or right the source of the image should change to previous or next image. I am saving the sources of the images in a LinkedList and updating the source accordingly.
I implemented the swipe to change image source using the following code
MediaControl.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY;
MediaControl.ManipulationStarted += (s, e) => { X1 = (int)e.Position.X; Y1 = (int)e.Position.Y; };
MediaControl.ManipulationCompleted += (s, e) => {
X2 = (int)e.Position.X;
Y2 = (int)e.Position.Y;
if (Math.Abs(X1 - X2) >= 50 && Math.Abs(Y1 - Y2) < 20)
{
{
if (X1 > X2)
{
NextPostButton_Click(s, e);
}
else
{
PreviousPostButton_Click(s, e);
}
}
};
};
I want to have zoom functionality in my image at the same time when source is changed, the image should be zoomed out. I want both the zoom and swipe functionality without each affecting the other manipulation. How do I do this? I am a beginner and have no experience in very complex Pointer events. If anyone could help me with this or point me to a good source for learning about this I would be eternally grateful.
Thank you.

Use a FlipView with a ScrollViewer inside of it and an Image inside of that. Then you just bind your FlipView's ItemsSource to a collection of Uri's. This will keep zoom functionality and swipe functionality automatically. Each image will retain its zoom factor as you swipe through your images. This works very well on mobile and desktops/tablets.
Let me know if you need some sample code. I'm on a phone right now so it's a little difficult to do source.

You can register the ManipulationDelta event, and use ManipulationDelta.Scale Property to take care of the zoom.
MediaControl.ManipulationMode = ManipulationModes.Scale | ManipulationModes.TranslateX;
private void MediaControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
MediaControl.Height = e.Delta.Scale * MediaControl.ActualHeight;
MediaControl.Width = e.Delta.Scale * MediaControl.ActualWidth;
}
For more information on ManipulationDelta, see to
https://msdn.microsoft.com/en-us/library/system.windows.input.manipulationdelta.scale(v=vs.110).aspx
For more information on ManipulationModes, see to
https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.input.manipulationmodes

Related

I can't get the correct coordinate of an image with mouse over C#

This is my first question ever on Stackoverflow. So I hope it for the best answer.
I want to get correct X and Y coordinate of an Image with mouse over Event (WFA .NET Framework).
Take a look at my cursor
The coordinate should be somewhere between 500 for X and 427 for Y, but I only get as I posted. I already maxed out the scroll. And I think the image resolution is correct, here's the image properties
Here's my code:
private void pbInput_MouseMove(object sender, MouseEventArgs e) {
mouseX.Text = e.X.ToString();
mouseY.Text = e.Y.ToString();
}
And I have a plan to zooming the image for the future, so I put "auto scroll" panel below the picture box.
Could you help me? Thank you so much.
PS: Sorry for my bad English
Try putting picturebox inside panel
set panel to:
this.panel1.AutoScroll = true;
and picturebox to
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this will allow panel to have scroll bars and picturebox will have its full size adjusted to actual picture size

How can i calculate the right coordinates?

I need help. I have a Picturebox and would now like to calculate given coordinates on the picture and then play them in the label. How can I do that best?
As seen in the picture.
If you then click on the image on it, then the data is entered in a list box.
Thank you for your help.
My Picture here: https://prnt.sc/puxyu6
In WPF this particular might for once be the hardest. WPF/UWP is designed for the MVVM, and I do not know anyone but beginners that programm outside of MVVM. And I can not think of way to do this with MVVM.
PictureBox is also the WinForms Element. The WPF equivalent is called Image.
Navigation aids like this are not a trivial thing. One reason there are so few of it. But it comes down to few step process:
Get the x and y pixel coordinates that was clicked, also in relation to that the overall display size of the Image. Usually the MouseClick Event would be the tool for that, but I can not find it. MouseDown or LeftMouseDown are the closest events.
If the entire image was shown with no zooming or cropping, it is now just simple math. If it was 20% of the X axis and 21% of the Y axis, it is pretty easy to figure out where 20% of X and 21 of Y is on the SourceImage.
If there was any zoom or crop, this has to be taken into account, otherwise it is 2.
Equate the Image Pixel position with the coordinates you know for it.
Part 1 would look like this and needs to be registered with the MouseDown or LeftMouseDown Event of the Image:
private void ContentControl_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//Unpack the sender
Image source = (Image)Sender;
//Get the click point
Point clickPoint = e.GetPosition(source);
//There is more then 1 height Property in WPF.
//The Actuall one is what you are looking for
//Unfortunately you get doubles for this and int for the other. Consider general advise regarding double math
double ElementHeight = source.ActualHeight;
double ElementWidth = source.ActualWidth;
//Do what you need to find the relative position
//Part 2
}
Hopefully someone else can give you a better answer.

Zooming and scrolling in Oxyplots

I have a question about zooming and scrolling. My scroll function doesn't work perfectly, but close enough. Instead of the Maximum value I want to change the ActualMaximum, but that one was protected.
plotBSITotalA.Model.Axes[0].Maximum = hScrollBarA.Value +
(plotBSITotalA.Model.Axes[0].ActualMaximum - plotBSITotalA.Model.Axes[0].ActualMinimum);
plotBSITotalA.Model.Axes[0].Minimum = hScrollBarA.Value;
Ok, here comes the real problem: When I have zoomed in or out, the scroll function won't work anymore in that specific plot Area, where it have been zoomed. Other plotArea's that weren't zoomed, will work perfectly.
Does somebody know, how I can scroll when I zoomed in??
May be, It can be done by connecting two enevts with two methods:
1. event emitted when scrollbar changed with method of changing axes range
2. event emitted when axes range changed with method of changing the scrollbar position
Quite a few views, so maybe still a problem.
As I understand it, your saying the auto scroll stops when you have zoomed back out and subsequently add new values to the series?
Can't find a formal solution, but this works for me
add this to your axis:
xAxis.AxisChanged += OnXAxisChange;
add the method
bool doAxisReset = false;
private void OnXAxisChange(object sender, AxisChangedEventArgs e)
{
//if zoomed fully out, then enable auto scroll
//
if ((e.DeltaMaximum == 0) && (e.DeltaMinimum == 0))
{
doAxisReset = true;
}
}
In the rendering code (ie when you get a new element that triggers autoscrolling) and before InvalidatePlot
if (doAxisReset)
{
xAxis.Reset();
doAxisReset = false;
}

Draggable control in WPF?

I'm kind of new to WPF although I have some experience in Forms, and I decided to finally try to figure out how to use WPF. So When I got to draggable controls, this is the code I came up with (I attempted to change it to work with WPF but the control just twitches everywhere):
private void rectangle1_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed) {
double x = this.Left + (double)e.GetPosition(this).X - (double)rectangle1.Margin.Left;
double y = this.Top + (double)e.GetPosition(this).Y - (double)rectangle1.Margin.Top;
rectangle1.Margin = new Thickness(x, y, rectangle1.Margin.Right, rectangle1.Margin.Bottom);
}
}
You want to use adorners to achieve dragging, resizing, rotating, etc.
Alternative:
Install NuGet package: Microsoft.Xaml.Behaviors.Wpf
Add this to root element:
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
And just place this inside your element:
<Grid>
<behaviors:Interaction.Behaviors>
<behaviors:MouseDragElementBehavior ConstrainToParentBounds="True"/>
</behaviors:Interaction.Behaviors>
</Grid>
If you want to do it by hands use following algorithm:
On MouseDown event: Save Mouse position, TopLeft position of control, and delta(offset) of these coordinates, and set some boolean field flag eg. IsDragStartted to true.
On MouseMove check that drag started and use Mouse position and offset to calculate the new value of TopLeft position of control
On MouseUp event set IsDragStartted to false
here is a pretty good article on the matter on MSDN. also, a quick search on Google revealse a veritable cornucopia of choices for you DnD dining pleasure.

Constraints on Image Width/Height on WP7 GestureListener

I added the GestureListener to an image i'm trying to have zoom like this Stack Overflow answer here: How to zoom in and zoom out Images in WP7?
The problem is that the image does not ever stop zooming, and covers other controls on the page. This covers a few important buttons on the page.
In addition, it allows the image to get so small that it's very hard to make it bigger, and allows the image to go so far off the screen where it's too hard to bring it back.
My goal is to:
Keep the image in the Grid Row it's assigned to, to not cover other controls.
Prevent the width/height of the image from getting to small
Prevent the Width/height of getting too big
Prevent the image from being dragged off the screen.
Is there a way to solve this? The Width/Height of the Image object are not modified by the GestureListener, so I cannot simply do
Image i = sender as Image;
if (i.Height == TOO_BIG)
return;
...
This blog post shows how to implement Pinch/Zoom scaling on an image: http://alvaropeon.wordpress.com/2011/03/10/implementing-pinch-to-zoom-images-in-wp7/ The solution presented there is to limit at 4x the original size, but you could whatever you want. If you want to constrain it to it's parent, then just get the ActualWidth and ActualHeight of the parent as use those as your limits.
I ended up fixing this and getting it work perfectly with the code from the following blog:
http://www.frenk.com/2011/03/windows-phone-7-correct-pinch-zoom-in-silverlight/
It's a very impressive set of functions for Pinch/Zoom. The issue I had about the image covering other controls was fixed by adding clipping to the Grid, which is detailed here:
http://www.codeproject.com/Articles/36495/Silverlight-ClipToBounds-Can-I-Clip-It-Yes-You-Can.aspx
I guess you can do it by restricting transform.ScaleX and transform.ScaleY in the below event handler.if initialScale < somelength ,then only do the code.
private void OnPinchDelta(object sender, PinchGestureEventArgs e)
{
transform.Rotation = initialAngle + e.TotalAngleDelta;
transform.ScaleX = initialScale * e.DistanceRatio;
transform.ScaleY = initialScale * e.DistanceRatio;
}

Categories