WPF - Prevent scaling of Image control + getting Actual Height - c#

Just recently I switched my Windows to 125% DPI scaling mode and found out that my app does things that I don't want it to do.
One of the problems is scaling of the image I am showing in the app. Let's assume it can be any image and for this example let it be a 600-pixel wide one. I want it to stay just like that. I'm ok with scaling the rest of the interface but this one particular Image control has to be exactly as wide as the Image is, and not scaled up to 125% (to 750 pixels). How can I achieve that? Should I change control size after some DPI-related event fires?
Also, the second question is, why WPF is lying to me? When I get ActualWidth it tells me 600 pixels, but Paintbrush isn't lying - I hope - and it shows 750 pixels when I measure width on the screenshot. Should I be checking this value after any particular event so that I get an actual ActualWidth?
Some code:
imgNav.Source = ImageManager.LoadBitmapImage(uri);
BitmapImage bimp = imgNav.Source;
imgNav.Height = bimp.PixelHeight;
imgNav.Width = bimp.PixelWidth;
...
txtFoo.Text = imgNav.ActualWidth.ToString();
Thank you in advance for any suggestions.

Related

RectangleToScreen and Windows Zoom Factor

I use this (C# .NET) call to quickly get an image of a control.
Rectangle rectToCapture = myControl.RectangleToScreen(myControl.Bounds);
However, this only works if my Windows display scaling is set to 100%. If I set the display scaling to 125% this rectangle is totally wrong. How can I capture the correct rectangle regardless of scaling?
Per #Jimi I had to make the form DPIAware.
https://social.msdn.microsoft.com/Forums/windows/en-US/4d3979d4-88df-44af-8b66-16b1d4d41d57/issue-with-vs2015-windows-form-dpi-and-screen-resolution?forum=winforms

2d Graphics advantages & disadvantages over 2d Images in WPF

I need to know whether there is any advantages or disadvantages on using 2d graphics in wpf over 2d images or not?
I mean if I'm going to display an ellipse in a wpf window which one is more useful and why? To create an Ellipse object or to create an Image control and then load an pre-designed ellipse image into it?
Does using 2D graphics have any advantages in the sense that they consume less memory or increase performance or anything like that?
Thanks in advance.
An Image is not realy good scalable.
An vector Graphics is.
On a high dpi display your Image with Width = 300 (Units not pixels) and Height = 300 (units) is on a Display with 96 dpi not bigger than a Display with 144dpi. But the Image on the 144 dpi display needs more Pixels for the same size.
1 Unit is 1/96 inch.
So it is better to have a scalable "image" than a fixed one.
Its one of the features of wpf that winform don't have! and the reason why you should not use Pixels as a Size / Width / Height / Position / etc.
Excursus:
In winform it is hard to programm a scalable programm. on high dpi monitors the font, buttons etc. looks very small. there was no option to solve this problem.
so windows programmed an algorithm that creates a bitmap of the programm and scales this up.
So: the progamms width and height is the same as before, but the user sees a much bigger one (the Bitmap). The user input is then recalculated on the real sized application; Everything is working fine - and looking fine.
Hope that helps and is correct.

Placemark - icon size GEplugin

once agian i need help from all the kind users.
Im using Interop.GEPlugin to develop an application to display certain points on the google earth globe, with different color circels. So far all of that is working, but the problem is the size of this placemark. i want i bigger, like alot!
The code to setting up the placemark is:
KmlIconCoClass icon1 = m_ge.createIcon("low");
icon1.setHref("http://www.wispresort.com/images/easier.jpg");
icon1.setW(3000);
icon1.setH(3000);
var style = m_ge.createStyle("");
style.getIconStyle().setIcon(icon1);
For some reason, when i only add either icon1.setH(3000) its getting higher, but when i add both it just goes back to the original size.. Did i misunderstand something? or is this just a simple mistake in the plug-in??
Hope you can help me, Thanks.
The GE plugin behaves strangley with icon sizes. Even if you provide a large image as an icon, GE attempts to scale that icon down to a default size around 32 pixels. The most effective way I have found to change the size of an icon is with the setScale() method of the kmlIconStyle. The scale is simply a multiplier. If you want a 32px default icon size to bee 3000 pixels, then you can set the scale to about 94 (32x94=3008). kmlIconScale.setScale(94);
KmlIconCoClass icon1 = m_ge.createIcon("low");
icon1.setHref("http://www.wispresort.com/images/easier.jpg");
var style = m_ge.createStyle("");
var iconStyle = style.getIconStyle();
iconStyle.setIcon(icon1);
iconStyle.setScale(98);
The other issue you will face is that GE will automatically scale icons to shrink as you zoom out, so there is so way I have found to make an icon stay at a set size at all scales
Documentation for kmlIconStyle.setScale

Image added to WPF canvas changes size

As part of an application, I have a canvas object <Canvas Name="canvas"/> into which I am trying to insert the components of a clock as follows
// Add Background
Image bg = new Image();
bg.SetValue(Canvas.ZIndexProperty, 0);
bg.Source = new BitmapImage(new Uri("images/background.png", UriKind.Relative));
canvas.Width = bg.Source.Width;
canvas.Height = bg.Source.Height;
canvas.Children.Add(bg);
// Add second hand
Image hand = new Image();
hand.SetValue(Canvas.ZIndexProperty, 10);
hand.Source = new BitmapImage(new Uri("images/hand.png", UriKind.Relative));
canvas.Children.Add(hand);
The first image (bg) appears correctly but the second one (hand) appears to be scaled (original size is 5 x 61 pixels, interrogating image size after creation shows it has become 6.66 x 84.02 display units)
(bg original is 130 x 130 pixels and shows as 130.4 in display units)
All the answers to my query that I can find (StackOverflow and Google) suggest DPI setting of image but both my images are 96 DPI (according to Paint)
I have tried moving the image declarations into the XAML (not a long term solution) but this makes no difference. I have tried changing the order in which I insert the images with no effect. I have set the canvas width/height explicitly in the XAML - no effect.
I have set the size of the image explicitly - again no effect.
Can anybody tell me what is going on?
added: Compiled using .net 4 on windows7 64bit
Resolved:
Paint was reporting an incorrect DPI setting for the image.
Paint.Net gave me the correct value and by changing this to 96 DPI the problem was resolved
Issue resolved: Paint was reporting an incorrect DPI. Using an alternate paint package (Paint.net) showed the DPI was different. Correcting this setting fixed the issue.
You haven't set Width and Height for the second image and this had probably caused the issue.
You can also try to disable image stretching by adding a line (this should at least not scale the image, even if the control is scaled):
hand.Stretch = Stretch.None;
Update: I've just noticed You've already tried setting the dimensions of the image. Try to set if in the code. I'm currently looking for another possible causes of this problem.
Update II: I see You've found a solution. I'm glad you've made it work :).

C# WPF resolution independancy?

I am developing a map control in WPF with C#. I am using a canvas control e.g. 400 x 200 which is assigned a map area of e.g. 2,000m x 1,000m.
The scale of the map would be: canvas_size_in_meters / real_size_in_meters.
I want to find the canvas_size_in_meters.
The canvas.ActualWidth gives the Width in DIU's (Device Independant Units). So, 400 DIU's is 400/96 = 4,17 inches, PROVIDED that the physical resolution of my monitor is 96 dpi.
However, using a ruler, I found that the physical resolution of my monitor is 87 dpi. (There are only few monitors that ACTUALLY have 96 physical dpi)
That DPI difference (10%) translates to a +10% difference in the actual map control width on screen.
How do I measure the size of a WPF control in inches EXACTLY and regardless of screen resolution and DPI setting ?
How do I measure the size of a WPF control in inches EXACTLY and regardless of screen resolution and DPI setting ?
This isn't actually possible, because for it to work, WPF would have to know the resolution (in terms of DPI) of your monitor. Sounds nice in theory, but in practice windows doesn't know this information. This is why windows itself always assumes 96dpi blindly instead of being smarter about it.
Even if there were some way to manually tell it, or if your particular monitor has a custom driver that does pass the correct information to windows, this isn't going to work on anyone else's computer, so windows doesn't pass this information on to any applications.
The best you can do is draw a scale like google maps does. You know that 1 pixel == 1 mile, so you can draw a 50 pixel line on your map, with a label saying "this line equals 50 miles"
There is way to compute current pixel size in mm or inches. As mentioned in the earlier posts, it is not a fixed value and would vary depending on the current resolution and monitor size.
First get the current resolution. Assume it is 1280x1024
Now get the monitor width in mm using GetDeviceCaps function. Its a standard windows library function.
int widthmm = GetDeviceCaps(deviceContext, HORZSIZE);
My monitor width is 362mm
So pixel size = 362/1280 = 0.282 mm
The accuracy of this method depends on the assumption that the display area covers the width of the monitor exactly.
So to answer the original question, the canvas size of 400 x 200 pixels would be
(400 * 0.282/1000) x (200 * 0.282/1000) in meters when shown on my monitor.
Thank you for you prompt reply.
I totally agree, but I didn't want to believe it in the first place. You see, there has to be an approximate calculation of the scale of the map if the map is used to display different layers of map data (scale dependant).
Most applications use a slider control with e.g. 10 discrete map levels to set the "scale".
Having an absolute scale is not crucial for the application, it would be nice to display an indicative scale, like 1:15,000.
An absolute scale would require for an extra variable monitorPhysicalDPI (initially set to 96) that if the uses chooses to change would give slightly better scaling (again it's not crucial). The size of the map control would be:
map.ActualWidth * (96/monitorPhysicalDPI) * inchesPerDIU, inchesPerDIU is 1/96
Again these are cosmetics.. Wouldn't it be nice if Windows knew the ACTUAL control's dimensions? (user would have to give information about the screen dimensions on OS setup, or simply installing the monitor INF file)

Categories

Resources