i am trying to develop a remote desktop apps with c#. so i have couple of question regarding mouse coordinate calculation based on picture box
suppose i have picture box and i want to capture mouse coordinate when i will move my mouse
on that picture box in c#?
if i click at location (200, 300) on my picture box. then how can i determine
programmatically resolution of picture box and convert that (200,300) coordinate based on
that resolution.
when i will send (x, y) coordinate to other machine and if that pc has resolution have like
1024x768 then what logic i need to use to convert (x, y) according to that pc resolution
if possible help me with small sample code for my question. thanks
This sounds like a trivial question, if it's something homework related, add a tag homework.
int remote_x = local_x * remote_width / local_width;
int remote_y = local_y * remote_height / local_height;
The dimensions of the picture box (local_width and local_height) can be determined e.g. by using pictureBox.Width and pictureBox.Height. The cursor coordinates, local_x and local_y can be requested or are part of the event data (e.g. of the MouseMove event).
Simple, the easiest way is to transform your coordinates to a normalized form (ranging from 0 to 1). Then you can use these normalized coordinates to calculate the mousePosition on another resolution. This way the devices don't need to know the other devices resolution.
So:
//First Normalize the clickPosition using the current resolution
//clickPos(200,300) and resolution(800,600) => normalized(0.25,0.5)
var normalized = clickPos/resolution;
//Now you can send this information to the other device
//The other device uses the normalized parameter to calculate the mouseClick with his resolution
//normalized(0.25,0.5) and otherResolution(1280,720) => otherDeviceClickPos(320, 360)
var otherDeviceClickPos = normalized * otherResolution;
If you know the resolution of the remote screen and you know the size of the picture box then it's simply ratios rounded off to an integer.
Related
I'm developing a mobile application (xamarin.android & c#). Situation is showing an image having a certain width, e.g. 2380 pixel. I'm using the "ShowPress"-gesture so that the user is able to mark s a point on the picture. Now I need the location on the picture.
The event gets a parameter that provides the values RawX as well as RawY relating to the screen. How can I get the size of the ImageView? I need it to determine the position on original bitmap.
public void OnShowPress(MotionEvent e)
{
var x = e.RawX;
var y = e.RawY;
How can I achieve this?
You could read this document : MotionEvent,
Position e.RawX/e.RawY is related to the screen :
Returns the original raw X coordinate of this event. For touch events on the screen, this is the original location of the event on the screen, before it had been adjusted for the containing window and views.
Position e.GetX/e.GetY is related to the view :
getX(int) for the first pointer index (may be an arbitrary pointer identifier).
Better understanding :
RawX/RawY that is guaranteed to return absolute coordinates, relative to the device screen.
While GetX()/GetY(), should return you coordinates, relative to the View, that dispatched them.
So you could use e.GetX()/e.GetY() to determine the position on your original bitmap.
I'm working on a Winforms app that contains a large map image (5500px by 2500px). I've set it up so the map starts in full size, but the user can zoom out to a few different scales to see more of the map. The user is able to drag the map around to shift what they are looking at (like Google Maps, Bing Maps, Civilization, etc.).
When the map is full sized (scale = 1.0), I am able to prevent the user from scrolling past the borders of the image. I do this by calculating if they are trying to move past 0, or past the image width - current window size, similar to this:
if (_currHScroll <= 0) {
_currHScroll = 0;
}
This all works just fine. But, when I zoom out on the map (thus, making the image smaller), the limits for the bottom and right of the map break down. I know why this happens--because the Transform that is performed basically "compresses" the map a little bit, and so what used to be a 5000 px image is now smaller, depending on the scale. But, my limiters are based on the image size.
So, the user can scroll past the end of the map, and just sees white space. Worse things happen, I realize, but if possible I'd like to keep them from doing that.
I'm sure there is a straight-forward way to do this, but I haven't figured it out yet. I've tried simply multiplying my calculation by the scale, but that didn't seem to work (seems to under-estimate the size initially, then over-estimate on the smallest sizes). I've tried calculating the transform location of the bottom right of the image, and using that, but it turns out, that number is inverted, and I can't find what it relates to.
I'm including my transform point method here. It works just fine. It tells me, regardless of zoom level, what pixel was clicked on the original image. Thus, if someone clicks on point 200, 200 but the image is scaled at .5, it will show something like 400,400 as what was clicked (but, as I said, I don't think the scale value is a multiplier--using this just for demonstration purposes).
public Point GetTransformedPoint(Point mousePoint) {
Matrix clickTransform = _mapTransform.Clone();
Point[] xPoints = { new Point(mousePoint.X, mousePoint.Y) };
clickTransform.Invert();
clickTransform.TransformPoints(xPoints);
Debug.Print("Orig: {0}, {1} -- Trans: {2}, {3}", mousePoint.X, mousePoint.Y, xPoints[0].X, xPoints[0].Y);
return xPoints[0];
}
Many thanks in advance. I'm sure it's something relatively easy that I'm overlooking, but after several hours, I'm just not finding it.
If i understand right, you can calculate the maximum with your method GetTransformedPoint by using width and height from your Image as Point. The result can then be used inside your check...
And by the way, you are right, the scale value is a multiplier used as a factor. The only thing is, you have to cast the result to an integer.
I want to draw text on the outline of a circle at fixed intervals (exactly like a clock)
Is there a simple way to do that?
Whatever graphics library you use, drawing text needs an x and a y to know where to draw the text.
Assume the center of the clock is Cx and Cy. Assume x goes positive to the right and y goes positive up. You may need to offset or reverse those depending on your platform.
So you can use math (trigonometry) to get the x and y of each clock number. You need the degree along the circle and the radius of the circle, and the formula would be:
y = sin(degree) * radius + Cy
x = cos(degree) * radius + Cx
toddmo's math is right. In terms of the implementation, it's not clear exactly what you are asking. If you are starting from scratch, the simplest way of doing this would be:
1) create a Windows Forms app in Visual Studio
2) draw the circle in mspaint, and import the image file as a resource.
3) create a picturebox that shows that resource using the form builder UI. This is an easy way to display the circle on the form.
4) create a 'Label' control by dragging and dropping it onto the form in the form builder UI
5) create a 'Timer' control (can be drag/dropped onto the form from the 'toolbox' window)
6) double-click the Timer control, in it's event, set the Label control's position based on sin and cos as toddmo describes.
7) set the interval of the Timer control to the appropriate value.
This won't scale well if dpi changes, but it's a start.
I have a chart that displays several lines showing signal strengths over a frequency band.
Each chart is composed of one 'area' and four 'series'. On the parent form there are several graphs like the one shown below. All of them are created dynamically and will have different widths.
What I am trying to do is add a tooltip or annotation (or something) when the mouse hovers over a specific area of the chart as shown in the mockup below:
If the mouse moved to the other side of the chart a different channel number and frequency would be shown in a box surrounding that area of the chart.
It doesn't have to be exactly as shown in the mockup although an outline would be preferred in order to show the user how wide the channel is regardless of the waveform shown in that area at the time. For example, the waveform shown above might only be 8MHz wide but channel 1 itself might have an allocation that is 10MHz wide (the device varies its bandwidth based on its offered load.)
The X axis is MHz and a channel is defined in terms of MHz so it would be ideal to define the outline in terms of the X axis instead of pixels.
Also, note that this is a realtime chart that is updated up to 10 times per second. Therefore it would be best if the information was not required to be updated each time new data arrived.
I was able to combine a couple of items to make the following solution:
[credit LICEcap]
The highlight is a rectangle filled in the 'OnPaint' method of the chart control.
The text is a simple TextAnnotation that is applied during the mousemove event.
It took quite a bit of coordinate conversion to get all the pieces in the right spot - especially the text. I needed to convert between pixels, position and value.
The first conversion was to pixels in order to center the text using MeasureString. I then converted it from pixel location to X axis value and then needed to convert it to position since the annotation requires using 'position' coordinates. There is not a function to convert from pixels to position. There is a pixels to value and a value to position which is the way I went.
I don't claim this to be the best or even a proper way to do it but it works. If anyone else has a better solution or a way to improve my code please post.
Here's my code for positioning the text:
double temp = chart1.ChartAreas[0].AxisX.ValueToPixelPosition(Convert.ToDouble(ce.sChannelFrequency) * 1000);
using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1))) {
SizeF size = graphics.MeasureString(freq.Text, new Font("eurostile", 13, FontStyle.Bold, GraphicsUnit.Pixel));
temp -= (size.Width/2+10);
}
if (temp < 0) temp = 0;
temp = chart1.ChartAreas[0].AxisX.PixelPositionToValue(temp);
freq.X = chart1.ChartAreas[0].AxisX.ValueToPosition(temp);
i have a big image about :(14848 PX width * 14336 PX height ) i used deep-zoom tool and exported the files to silverlight, and used a 'multi scale image' control.
the multiscaleimage is 400*400 px .
after the projects starts i want when i click on some where in the image to know the 'real' coordinates for the real image not for the width of the multiscale control,considering the panning and the zooming factor...
so if there is a way to know that.i hope you guys help me.
thanx in advance.
The MSDN docs on this are hopeless. This blog post actually defines the terms:
Logical Coordinates – is a normalized value (0 to 1) representing a coordinate in the image itself (not the control)
Element Coordinates – is the actual control coordinates. For example in a MultiScaleImage of Width=800, Height =400, when the mouse is at the center, the element coordinates are 400,400. These coordinates are not normalized.
[I copied that definition from the blog post, but the example seems to be wrong: the element coordinates should be 400,200.]
It's clear then that you want MultiScaleImage.ElementToLogicalPoint to convert mouse coordinates to image coordinates.
The image coordinates are in the range [0,1]. Simply multiply by the original image width/height to get pixel coordinates in the original image.