In my application i need to know size of all monitors combined space, to adjust size of the window if it goes to big.
I found VirtualScreenWidth and VirtualScreenHeight in System.Windows.SystemParameters and it seems like what i need. But also i wonder what is VirtualScreenLeft and VirtualScreenTop and how i should take it in consideration? In which scenarios this values are set to not 0?
The virtual screen is the bounding box containing all the monitors of the system. The bounding box is referenced at 0,0 being the upper-left corner of the main monitor (the main-monitor is defined in the system properties).
This means that the bounding box can have negative numbers as the Left/Top values. For example, lets say you have 2 1920x1080 monitors. The main monitor is set to the one on the right (but level at the top), the bounding box will be -1920,0,3840,1080 (x,y,w,h).
If you move the left monitor up 500 pixels, the bounding box becomes -1920,-500,3840,1580. Its important to note that some areas of the bounding box will not be visible to the user, so if you are designing a screen that takes up as much area as both monitors have, be aware that they may not be set up in a rectangular shape. They also may not be both the same resolution.
Related
Let's suppose that I have two screens, side by side:
1920x1080 100% DPI
1360x768 125% DPI
For my Window, this means:
1920x1080: Ok
1088x614: Not ok, it's divided by 1,25 because of the scaling factor.
Turning into this:
1920x1080 + 1088x614: 3008x1080
I want to use the CopyFromScreen/BitBlt methods.
These methods ignore all DPI info, making the Left and Top properties (of a window, for example) useless if inside a high dpi screen. Or left to a high dpi screen, since it behaves like 1 screen, example:
So whenever I need to get a screen point from within a set of screens with at least one having a high DPI, it will return a smaller point.
Is there any way to get the true (by true, ignoring the scaling factor) XY info from a set of screens with (at least one) high DPI?
I already tried the managed PointToScreen and the unmanaged ClientToScreen methods, both resulting the same "right" point.
Please, read
I want to take screenshots of the screen based of the position of my Window.
I have two monitors, one with 100% DPI, other with 125% DPI.
If my Window is inside the 1st monitor, the screenshot based on the Left/Top properties of my Window works.
If my Window is inside the second monitor, the screenshot won't take the right spot!
Because
The BitBlt API method ignores the scaling of the screens. Example:
Screenshot of the point 100;100 will be right, because it's inside the 1st screen.
Screenshot of the point 1950;100 won't be right, because it's inside the 2nd screen. Notice that it's 30 pixels to the right.
Why?
As said earlier, for my app, the 125% DPI reduces the screen resolution to 1088x614, but for the BitBlt method, it is still 1360x768.
So I can't convert the Left/Top properties, because it will be wrong, since there is a 100% DPI screen to the left.
Example of the Left property:
I believe this is the right way to convert:
1920px + 50px: 100% + 125%: 1920 + 62: 1982px
And this is the proposed version:
1920px + 50px: 100% + 125%: 2400 + 62: 2462px
See, if I simple convert the current Left property based on the DPI of the current Window, on this case my second screen, I'll also be converting the values of my first screen. This should not happen.
I am creating a visualizer in WPF to display flowfield information for a game I am writing and have come across a problem with some labels being very close to each other.
In the above screen shot, sector (0,0) is the top left. In sector (1,1) I have highlighted two labels with arrows that are very close to each other. In sector (2,1) I have circled two labels that overlap completly. I need to be able to place labels in a way so that they do not overlap and have a margin of distance. I am after preferably a simple algorithm that allows me to place labels on a contended spot.
The blue/black cells are virtualized items on an Items Control with a canvas as the ItemsPanel. The red sector squares are on one adorner while the green lines, boxes, bezier curves and red cost labels are on a second adorner. Both adorners use the drawing context with everything dynamically created upon render.
var typeface = new Typeface(new FontFamily("Segoe UI"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
var formattedText = new FormattedText(curve.Cost.ToString(), CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, typeface, 12, Brushes.Red, null, TextFormattingMode.Display);
var textLocation = new Point(midPoint2.X - (formattedText.WidthIncludingTrailingWhitespace / 2), midPoint2.Y - formattedText.Height);
drawingContext.DrawText(formattedText, textLocation);
A suggestion:
The Voronoi diagram of a set of geometric entities is the partition of the plane into regions where points are closer to a given entity than to all others.
If you construct the Voronoi diagram of your curves, and if you place the labels wholly in the corresponding regions, this solves your problem.
Assuming that all labels have the same extent (same bounding box), you can find suitable empty spaces by applying an erosion operation, i.e. removing layers of pixels on the region outlines for the desired width/height. The remaining pixels are possible centers for the labels.
In the general case, computing a Voronoi diagram by geometric means is extremely difficult. But if you work with a digital image, it suffices to draw the geometric entities and compute the distance map from them.
This requires that you be somewhat familiar with the techniques of digital image processing.
After considering several ways to place labels includng
Word Clouds, physics based approaches, voronoi diagrams. I decided to base my approach on An Empirical Study of Algorithms
for Point-Feature Label Placement as I could see a simple and quick way to position labels. Page 2 gave me the idea of having four possible locations for a desired point and I built my own implementation with very simple rules.
I created a class called PointLabelPlacer with two methods
AddLabel
ComputeNewPositions
I would send all my labels along with the point to the AddLabel method.
Once I was done and ready I would call ComputeNewPositions. This would for all four possible locations count the number of locations from another labels that have overlapped.
I would also flag a location if it overlapped an original point of another label.
If two labels overlapped exactly, i would again choose the first one without overlaps, but I would mark all the other labels location as used
Then I would just choose the first one I found with the lowest number of overlaps and did not overlap another point and was not marked as used.
If after all that no alternate location could be found, I default to the top left and allow overlaps.
This is with the alternate locations displayed in yellow
This is the final result
I am working on project in ASP.NET WEB APPLICATION in which I am having problem with screen Resolution. Whenever I connect my project execution to different devices like from laptop to monitor or to Projector, the fields, labels, drop down lists and other are randomly displaced on the screen. I want to have same display look irrespective of the device on which the out put is being seen. I have seen so many ways but I couldn't find the one which suits my scenario.I want to adjust the out put to be displayed in same way when the resolution is changed that is like from 1024*768 to 1280*1024, etc. I want the out put to be spread across the entire screen in same manner irrespective of the resolution.In the project the resolution for all the controls is declared in measure of pixels not on percentage based.I don't want to change pixels into percentage that makes me to change every where in the project but by keeping them as pixels I want to adjust the resolution whenever it is changed so that the controls will be evenly displaced. Please help me with this.
Set up a displacefactor, that displaces "objects" on x, and y axis by a value calculated from the resolution. I'd check if the "object" is on the left or the right side of the screen (by getting the width of the screen and if its bigger than the half then displacefactor is poisitive, if not then its negative, and you displace the object on the x axis), you can do that with the height so you can displace them on the y axis. I can't be more specific because i can't program C# nor javascript, but i hope you understand what i'm trying to explain.
I'm working on an experimental project in which the challenge is to identify and extract an image of the icon or control that the user is has clicked on/touched. The method I'm trying is as follows (I need some help with step 3):
1) Take a screen shot when the user clicks/touches the screen:
2) Apply edge detection:
3) Extract the possible icon images around the Point associated with the user's cursor (Don't know how to do this)
There are easier cases in which the mouse-over event will highlight the icon/control, which allows me to identify the control with a simple screen shot comparison (before and after mouse-over). The above method is specifically for cases in which the icon is not highlighted. I'm new to emgu, so if anyone has any pointers on how to better achieve this, I'm all ears.
Cheers! Matt
Instead of doing edge detection. Consider taking the following steps:
Only grab pixels which are within a certain radius of the point of the user's cursor. Create a new image with just these pixels.
Use thresholding to classify into foreground and background.
Calculate the centroid, (use mean x coordinate and mean y coordinate). Calculate deviation from the mean. Discard foreground pixels which are beyond a certain deviation from the mean. Eg: discard pixels that are more than 1.6 deviations from the mean.
(You may need to experiment with this step ).
Use a convex hull to find the area of the image with the icon in it.
I want to create some heat-map style tiles to overlay over our base maps using Open Layers. Basically, I want to divide some some bounding box into a grid, and display each square of the grid using a different color based on how many points of a sample fall within that grid square.
The technologies involved are C#, OpenLayers, SQL Server 2008 and GeoServer.
My question is basically one of general approach, I'm not really sure where to put the tip of the chisel on this one.
My ultimate goal is to be able to take any arbitrary bounding box, calculate an x-mile by x-mile grid that fits within that bounding box, the iterate over a collection of individual points and assign them to one grid square or another so I can calculate point density per grid square, then color the grid according to the densities, then overlay that on a CloudMade base map using Open Layers.
Any help at all would be greatly appreciated, on the whole thing or any piece of it.
If your bounding box is axis aligned, this is fairly simple. Just make your image, and create a world file for it by hand. The world file is just 6 lines of text, and you already know everything needed (x & y pixel size, coordinate of your upper left corner).
Just make sure that you use the CENTER of the upper left corner pixel, not the corner of the box.
------ Here's how you'd make the world file -------
Say your bounding box's upper left corner is at 203732x598374, and you want an image that has rectangles that are 200m wide east<->west and 300m tall north<->south.
You'd make an image that was the appropriate number of pixels, then a world file that had the following 6 lines:
200
0
0
-300
203632
598524
This corresponds to:
200 == size of one pixel in X
0 == shear1
0 == shear2
-300 == size of one pixel in Y (from top down)
203632 == left edge - 1/2 pixel size (to center on pixel instead of edge of box)
598524 == top edge - 1/2 pixel size (to center on pixel instead of edge of box)
If you use a .png image, you'll want to save this with the same name, but as .pgw. If you use a .jpg, it'd be .jgw, etc.
For complete details, see:
Wiki on World Files
"Dividing some some bounding box into a grid, and displaying each square of the grid using a different color based on how many points of a sample fall within that grid square." This is a raster and there are features in GeoServer for displaying these with colour shading, legends and so on. I think it will be more flexible to use these features than to create image tiles in C#.
From the GeoServer documentation:
Raster data is not merely a picture,
rather it can be thought of as a grid
of georeferenced information, much
like a graphic is a grid of visual
information (with combination of reds,
greens, and blues). Unlike graphics,
which only contain visual data, each
point/pixel in a raster grid can have
lots of different attributes, with
possibly none of them having an
inherently visual component.
This is also called thematic mapping or contour plots or heatmaps or 2.5D plots in other GIS packages.
You could use a free GIS like Grass to create the raster grids, but from your description you don't need to interpolate (because every cell contains at least one point) so it might be just as easy to roll your own code.
EDIT: there is an open source library GDAL which you can use to write raster files in various formats. There are C# bindings.
I think the formulas for computing the center of the upper left pixel are wrong. In the example, the center of the upper left pixel would be down and to the right of (203732,598374). So shouldn't it be the following?
203832 == left edge + 1/2 pixel size (to center on pixel instead of edge of box)
598224 == top edge - 1/2 pixel size (to center on pixel instead of edge of box)