Xaml, wpf image position and crop issue - wpf

I have images of 600px width and 600px height. we have three sizes of circles. all have the center in the middle. Some have reflection as shadow beneath it. I would like to crop the image for display purposes.
So the largest circle as shown above has a diameter of about 500 pixels, but the medium and small ones have less. I know in the code which size I have of object type Product. Because of the size differences I have to place them differently and used three placeholder images for it, like this:
<Image x:Name="imgCoinHolderSmall"
HorizontalAlignment="Center"
Margin="0,495,0,0"
VerticalAlignment="Top"
Stretch="Fill"
Width="200"
Height="200"/>
<Image x:Name="imgCoinHolderMedium"
HorizontalAlignment="Center"
Margin="0,510,0,0"
VerticalAlignment="Top"
Stretch="Fill"
Width="200"
Height="200"/>
<Image x:Name="imgCoinHolderLarge"
HorizontalAlignment="Center"
Margin="0,520,0,0"
VerticalAlignment="Top"
Stretch="Fill"
Width="200"
Height="200"/>
So can I change the properties of the image such that it does not display the red part of this screenshot:
By the way, I do not display the images on their original size (as you can see at the xaml code) I set the width to 200. It is just a display thing, I do not have to store the new image. I would like to do it on the fly, preferably by setting image properties in the xaml. (for all three sizes of circles)
Is using the CroppedBitmap the best approach? http://msdn.microsoft.com/en-us/library/ms752345.aspx it is for windows rt by the way.

One option would be to use a clipping mask:
<Image Source="MyImage.jpg">
<Image.Clip>
<RectangleGeometry Rect="10,10,80,80"></RectangleGeometry>
</Image.Clip>
</Image>
The rect structure takes X,Y, Width and Height values that you have to set depending on your image.

Related

Image is displayed in large size and cropped even if size declared is same as source

I have a png image with size 30x30. Then i created an image inside a button using my 30x30 image:
<Button>
<Image x:Name="Sample" Source="sample.png" Stretch="None" SnapsToDevicePixels="True"
Width="30" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
But still the image is displayed big and cropped in the Image control. Why does this happen even they have the same size?
The image in sample.png might have different DPI than 96, which WPF uses as the size of its device independent units.
Just don't set Stretch="None" on the Image element in order to get it scaled correctly. The default value of Stretch is Uniform.
<Image Source="sample.png" Width="30" Height="30"/>
You can check the difference between the native size and the (unstretched) rendered size of an image if you load it into a BitmapImage and compare its Width and Height with its PixelWidth and PixelHeight.

Get scaling factor of an image when the image goes out of grid

I have a grid that contains an image.
<Grid Name="grid1">
<Image Name="image1" Stretch="None" Source="C:\Users\User\Desktop\image.jpg"/>
</Grid>
If the size of image was greater than the size of the grid, I want to scale it manually by render transform to fit the grid. I don't want to use Stretch="Fill" because I need the scale factor.
Is there any way to detect the situation that an UIElement goes out of view?
I need your help.
You could simply set the Stretch property to Uniform (or perhaps Fill) and calculate the scaling factor from the ActualWidth of the Image and the Width of the ImageSource, whenever you need it. The sample below does the calculation in a SizeChanged handler, but it could be anywhere else.
<Image Name="image1" Stretch="Uniform" Source="C:\Users\User\Desktop\image.jpg"
SizeChanged="ImageSizeChanged"/>
The calculation looks like this:
private void ImageSizeChanged(object sender, SizeChangedEventArgs e)
{
var scale = image1.ActualWidth / image1.Source.Width;
}
As Uniform is the default value of the Stretch property, you wouldn't have to set it at all.
I'm not sure why you would want to rescale your image manually when WPF can do it for you...
Instead of putting the image straight into the grid, use a Viewbox control:
<Grid Name="grid1">
<Viewbox>
<Image Name="image1" Stretch="None" Source="C:\Users\User\Desktop\image.jpg"/>
</Viewbox>
</Grid>
The Viewbox will automatically scale the picture to fit inside the grid...

How to deactivate scaled image preliminary smoothing?

I've got a Grid with some scale transform applied; the Grid contains an image:
<Grid Background="Black">
<Grid.LayoutTransform>
<ScaleTransform ScaleX="5.7" ScaleY="3.7"/>
</Grid.LayoutTransform>
<Image Source="rw.bmp" VerticalAlignment="Top"/>
</Grid>
The image is 2 by 1 pixels, one pixel red and one white:
I expect to get such a rendered image (stretched):
but I actually get this one (again stretched):
You can see that the actual rendered image is somehow kind of smoothed before stretch, instead of being smoothed after stretch.
Is there a way to get the image as in the expected example?
Edit: tried different values of RenderOptions.BitmapScalingMode. The closest to what I need is "NearestNeighbor", which gives the following:
I'm not positive, but could you somehow use RenderOptions.BitmapScalingMode with this?

String Length in Pixels

How can I obtain the lenght of a string (given a font , size weight etc) in Pixels? I have seen recomendations to try System.Drawing.Graphics.* but that Assembly / Namespace doesn't seem to be available to me in silverlight.
I hope to center a text box under an image, but the text is provided dynamically.
Since your goal is to Centre the TextBox don't mess around with calculating width etc. Just tell the Container to centre the textbox.
eg.
<Grid>
<Image Source="ToolBox Avatar.png" Stretch="Fill"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="TextBlock" TextWrapping="Wrap"/>
</Grid>
Thought I not familiar with developing for Silverlight, I think that this might be of use to you.

In WPF, view a portion of an image

We have an image where we create view box coordinates that are topleft/bottom right points within the image that are setup to allow for viewing portions of an image at different times in our application. In WPF, how do we load an image, and with topleft/bottom right points within that image, only show the portion of the image within that view box?
You can do this with a CroppedBitmap:
<Image>
<Image.Source>
<CroppedBitmap Source="<path to source image>" SourceRect="20,20,50,50"/>
</Image.Source>
</Image>
This will display the 50x50 region of the image starting at position (20,20)
Using a RenderTransform with a Clip works even better, because the CroppedBitmap is kinda immutable:
<Image x:Name="MyImage">
<Image.RenderTransform>
<TranslateTransform X="-100" Y="-100" />
</Image.RenderTransform>
<Image.Clip>
<RectangleGeometry Rect="0 0 250 250" />
</Image.Clip>
</Image>
This will display the image at offset (100, 100) with a size of (150, 150), so don't forget the rect must include the startoffsets.
Here's a method to calculate it in code:
public static void ClipImage(System.Windows.Controls.Image image, Rect visibleRect)
{
image.RenderTransform = new TranslateTransform(-visibleRect.X, -visibleRect.Y);
image.Clip = new RectangleGeometry
{
Rect = new Rect(
0,
0,
visibleRect.X + visibleRect.Width,
visibleRect.Y + visibleRect.Height)
};
}
It seems to me that you can make the image control a part of the viewbox as shown below:
<Viewbox Name="vBox" Stretch="None" HorizontalAlignment="Left"
VerticalAlignment="Top" Height="50" Width="50">
<Image Name="ClippedImage"
Source="{Binding NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}"
Stretch="None" />
</Viewbox>
This will give you a view box 50x50. obviously you can change the height and width to suit your needs. I use a scrollviewer to pan around the smaller viewbox.

Resources