I am working on a C# Silverlight application that needs some text rotated 90 degrees CCW and for it to be center within an image that is 100px x 221px. The rotation part was easy to do in the design view, but centering the text has been a nightmare. (I am using a 16px font that cant be changed or resized)
My text is dynamic and can be one or two lines. When it is two lines long I can center it fine...but if It is only one line long, I cannot center it. The only way to center it so far is to resize the box and move it to the right.
Is there an easy way of doing this?
alt text http://www.freeimagehosting.net/uploads/f0435a8c65.png
The answer turned out to be simple:
<Grid x:Name="LayoutRoot">
<Image x:Name="Background" Source="Background.png" Stretch="Fill"/>
<TextBlock x:Name="Title"
Margin="-19.75,68.25,-21.25,67.806" Text="Here is some text to fill this up"
Foreground="#FF00A33D"
FontSize="22" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto"
TextAlignment="Center" TextWrapping="Wrap"
>
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-90"/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
Then in the cs file set the alignment when you change the text
Title.VerticalAlignment = VerticalAlignment.Bottom;
Related
I am new to working with skiasharp with avalonia. I looked at the documentation and examples of how to make some basic shapes, like circles, rectangles, etc. Can anyone give advice or suggestion on how to make a crossed circle filled with color? I think it would be best to do UserControl, something like in wpf.
How you package this up (UserControl) really depends on the use case and intention of the UI element.
<Viewbox x:Name="Vol2"
Width="25"
Height="25">
<Canvas Width="100" Height="100">
<Ellipse x:Name="MyCirlce" Width="100" Height="100" Fill="Black">
</Ellipse>
<Rectangle Height="50" Fill="White" Width="15" Canvas.Top="50" Canvas.Left="42.5" RenderTransformOrigin="0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="45"></RotateTransform>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
</Viewbox>
A ViewBox scales it's content, like an SVG.
We then plop a Canvas in there and add our Ellipse. We then add a Rectangle and position in (Left, Right) and then add a RotateTransform.
This should get you going.
I'm having a weird issue that causes an Image to get distorted if I re-size the window to a particular size. I'm assuming the image is being positioned inside the scrollviewer to a sub pixel position , but I'm not really sure how to fix this.
I'm using a Scaletransform, but the current issue is happening if the scale is set to 1.
If you Look at the Text in the screenshot below you'll see the text is slightly distorted , If i re-size the window by a single pixel , the distortion goes away as seen in the alternate screenshot.
Pixel Distortion
No Distortion
XAML Code:
<ScrollViewer x:Name="scrollViewer"
Background="#282828"
Focusable="False"
Grid.Column="2"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible" SnapsToDevicePixels="True">
<Border BorderBrush="Red" BorderThickness="1">
<Grid Name="grid" RenderTransformOrigin="0.5,0.5" SnapsToDevicePixels="True">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform x:Name="scaleTransform" CenterX="0.5" CenterY="0.5" />
</TransformGroup>
</Grid.LayoutTransform>
<Image Name="img" HorizontalAlignment="Left" VerticalAlignment="Top"
IsHitTestVisible="False"
RenderOptions.BitmapScalingMode="NearestNeighbor"
SnapsToDevicePixels="True"
Stretch="Uniform" />
</Grid>
</Border>
</ScrollViewer>
Just a hunch: Have you tried to apply UseLayoutRounding?
I want to crop an image in wp7 such that only some part of it appears in an imagebox (or just the 'image' control). I used image.clip, but it actually retains the whole image, and just whitens the 'to-be-cropped' portion. How can i crop the image so that the cropped image is the resultant image?
Note: I am looking for a way in xaml
This is working for me just fine with Light and Dark themes. I'm showing a square image inside an ellipse clip and adding a border around it; it's not showing through.
<Grid>
<Ellipse
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="78"
Height="78"
StrokeThickness="5"
Stroke=""/>
<Image
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="UniformToFill"
Source="{Binding MediumPhotoUrl}"
Width="64"
Height="64" >
<Image.Clip>
<EllipseGeometry RadiusX="32" RadiusY="32" Center="32,32"/>
</Image.Clip>
</Image>
</Grid>
Are you sure you're doing clip correctly?
If you know the size of the initial image, you can calculate the required transforms, for example:
<Image Width="100" Height="100">
<Image.Clip>
<!-- Image after clipping takes only a small area in the center -->
<RectangleGeometry Rect="25,25,50,50"/>
</Image.Clip>
<Image.RenderTransform>
<!-- Transforms Rect(25,25,50,50) into Rect(0,0,100,100) -->
<TransformGroup>
<TranslateTransform X="-25" Y="-25"/>
<ScaleTransform ScaleX="2" ScaleY="2"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
I don't know a way of doing it automatically (without code behind).
I have the following custom UserControl that represents a card in my application:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:Core="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Namespace="clr-namespace:MyApp" xmlns:Properties="clr-namespace:MyApp.Properties" Core:Class="MyApp.Card" Height="176" RenderTransformOrigin="0.5,0.5" Width="83" UseLayoutRounding="True">
<UserControl.LayoutTransform>
<TransformGroup>
<RotateTransform/>
<ScaleTransform/>
</TransformGroup>
</UserControl.LayoutTransform>
<UserControl.RenderTransform>
<TransformGroup>
<RotateTransform/>
<ScaleTransform/>
</TransformGroup>
</UserControl.RenderTransform>
<UserControl.Resources>
<Namespace:ImagesConverter Core:Key="ImagesConverter"/>
</UserControl.Resources>
<Canvas Core:Name="Layout">
<Image Core:Name="Image" HorizontalAlignment="Left" Source="{Binding Source={Core:Static Properties:Resources.Cards}, Converter={StaticResource ImagesConverter}}" Stretch="None" VerticalAlignment="Top">
<Image.Clip>
<RectangleGeometry Core:Name="Clipping" Rect="0,0,83,176"/>
</Image.Clip>
<Image.RenderTransform>
<TranslateTransform Core:Name="Translation" X="0" Y="0"/>
</Image.RenderTransform>
</Image>
<Rectangle Core:Name="Highlight" Canvas.Left="-2" Canvas.Top="-2" Height="180" Opacity="0.7" Stroke="#FFFFF500" StrokeThickness="3" Visibility="Collapsed" Width="87"/>
</Canvas>
</UserControl>
As you can see... I have a bit PNG image containing all the card faces and then, when I create a new card passing Suit and Rank enum values in constructor, I calculate the correct clipping rectagle and translation for the image.
Everything works like a charm... except when I try to animate my card with a Storyboard that requires a 90° rotation. Here is my code (the Storyboard is defined in MainWindow.Resources):
<DoubleAnimation BeginTime="00:00:00.4" Duration="00:00:00.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)" To="90"/>
And here is the result:
I can't understand what's going on... but the images gets somehow stretched and becomes very blurry as you can see. I tried using UseLayoutRounding="True" in my card control and also SnapsToDevicePixels="True" in my MainWindow as suggested somewhere else... but it's not working!
Of course... if I rotate the card using LayoutTransform instead of RenderTransform everything works perfectly and the card is not blurry... but I can't make the card rotate around it's center and my animation requires a 90° rotation from the center. Animating Canvas.Top for half of the card height together with layout rotation looks to me like a very unbrilliant solution... and it also makes my animation looks very bad.
Can you suggest me a solution please?
[EDIT] I tried to use RenderOptions.BitmapScalingMode="NearestNeighbor" and RenderOptions.EdgeMode="Aliased"... but it becomes even worse:
The problem was that the underlying image, and so the layout, had an odd value as Width (83). RenderTransformOrigin, even if set to "0.5,0.5", was probably rounding up or down that value resulting in a very bad rendering.
Changing both the image and layout Width to a even value (82), totally resolved the problem.
You could try changeing the RenderOptions on the Image and see if you can find a setting that works, I have added an example of settings I use for this exact situation in my application
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased"
Example:
<Image RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased"
Core:Name="Image" HorizontalAlignment="Left" Source="{Binding Source={Core:Static Properties:Resources.Cards}, Converter={StaticResource ImagesConverter}}" Stretch="None" VerticalAlignment="Top">
<Image.Clip>
<RectangleGeometry Core:Name="Clipping" Rect="0,0,83,176"/>
</Image.Clip>
<Image.RenderTransform>
<TranslateTransform Core:Name="Translation" X="0" Y="0"/>
</Image.RenderTransform>
</Image>
You indicated that using LayoutTransform works perfectly without blurring the image. Have you tried using it and specifying the center as the pivot of rotation?
Something like:
<Image ...>
<Image.LayoutTransform>
<RotateTransform CenterX="0.5" CenterY="0.5" Angle="90"/>
</Image.LayoutTransform>
</Image>
As #Tommaso Belluzzo said, this is cause from RenderTransformOrigin="0.5,0.5"
Your answer above really solved my question.
Allow me to show my code as following:
System.Drawing.Bitmap bm = null;
//RotateTransform(angle) with RenderTransformOrigin="0.5,0.5" might cause blurry if the width or height is odd,
using (System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(path))
{
int width = bitmap.Width;
int height = bitmap.Height;
if (0 != width % 2) width ++;
if (0 != height % 2) height ++;
bm = new System.Drawing.Bitmap(width, height);
bm.SetResolution(96, 96);
using (System.Drawing.Graphics g = System.Drawing. Graphics.FromImage(bm))
{
//I don't want to do anything which may modify(resize) the original image.
g.Clear(System.Drawing.Color.White);
g.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
}
//bm.Save(directory+#"\tmp.bmp", ImageFormat.Bmp);
}
//.....(show bm)
Ok,
So I've tried to make an application which relies on images being scaled by an individual factor. These images are then able to be turned over, but the use of an animation working on the ProjectionPlane rotation.
The problem comes around when an image is both scaled and rotated. For some reason it starts bluring, where a non scaled image doesn't blur.
Also, if you look at the example image below (top is scaled and rotated, bottom is rotated) the projection of the top one doesn't even seem right. Its too horizontal.
http://img43.imageshack.us/img43/5923/testimages.png http://img43.imageshack.us/img43/5923/testimages.png
This this the code for the test app:
<UserControl x:Class="SilverlightApplication1.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Canvas x:Name="LayoutRoot" Background="White">
<Border Canvas.Top="25" Canvas.Left="50">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="3" ScaleY="3" />
</TransformGroup>
</Border.RenderTransform>
<Border.Projection>
<PlaneProjection RotationY="45"/>
</Border.Projection>
<Image Source="bw-test-pattern.jpg" Width="50" Height="40"/>
</Border>
<Border Canvas.Top="150" Canvas.Left="50">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup>
</Border.RenderTransform>
<Border.Projection>
<PlaneProjection RotationY="45"/>
</Border.Projection>
<Image Source="bw-test-pattern.jpg" Width="150" Height="120"/>
</Border>
</Canvas>
</UserControl>
So if anyone could possible shed any light on why this may be happening, I'd very much appreciate it. Suggestions also welcome! :)
** Update **
Just to clarify, if the projection plane rotation is 0, the image becomes un-blurred, so its only during the rotation that the image is blurred.
The top image's width is set to 50 and the height to 40. So it is downscaled. Afterwards you scale it up to the right size 150, 120. I guess Silverlight scales the image down and doesn't store the original size due to performance optmization. Leave the Scale out and set the right width and height for the first image.
It looks like the top image is being filtered as it is being drawn. From your code you have:
<Image Source="bw-test-pattern.jpg" Width="50" Height="40"/>
for the top image and
<Image Source="bw-test-pattern.jpg" Width="150" Height="120"/>
for the bottom one. You have different image sizes so the top one might be being upscaled and therefore blurred as it interpolates the missing pixels.
I'm not familiar with silverlight so I don't know how you'd control the filtering options, but setting the top line above to the same as the bottom one might fix it.