UWP / WinRT Generate Path from multiple rects - c#

How I can create a custom path from two or more rectangles?
I am working with xaml / UWP and the fill color have to transparent.
Current State;
Needed State;
Currently I am using following code:
GeometryGroup path = new GeometryGroup();
path.Children.Add(new RectangleGeometry() { Rect = new Rect(0, 0, 100, 100) });
path.Children.Add(new RectangleGeometry() { Rect = new Rect(30, 30, 150, 100) });
Data = path;
<Path HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10"
Data="{Binding Data}"
Stroke="Blue" StrokeThickness="5" Opacity="1" />

Related

Why window smaller than actualwidth?

I want capture window but The actual window size seems to be smaller than the figure.
this is code
<Window x:Class="FileRead.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="620" Height="340" >
<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="ReadImageButton" Width="100" Height="30" Margin="10" Click="ReadImage_Click">
LoadImage
</Button>
<Button x:Name="ReadTextButton" Width="100" Height="30" Margin="10" Click="ReadText_Click">
LoadText
</Button>
<Button x:Name="CaptueScreenButton" Width="80" Height="30" Margin="10" Click="CaptueScreenButton_Click">
ScreenCapture
</Button>
<Button x:Name="CaptuerWindowButton" Width="80" Height="30" Margin="10" Click="CaptuerWindowButton_Click">
WindowCapture
</Button>
I couldn't find a problem.
private void CaptuerWindowButton_Click(object sender, RoutedEventArgs e)
{
int width = (int)this.ActualWidth;
int height = (int)this.ActualHeight;
Point point = this.PointToScreen(new Point(0, 0));
CheckLable.Content = string.Format("{0} / {1}", this.Width, this.ActualWidth);
using (Bitmap bmp = new Bitmap(width, height))
{
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.CopyFromScreen( (int)point.X, (int)this.Top, 0, 0, bmp.Size);
}
bmp.Save(ImagePath + "/WindowCapture.png", ImageFormat.Png);
}
}
result image
There is always a difference of about 15 points.:
help me please.
enter image description here
The cause of your problem is that size of a window include the area that draw by OS, which was called "non-client area", usually include frame, border, drop show effect. And your calculation didn't consider that. The right code will like
var clientTopLeft = this.PointToScreen(new System.Windows.Point(0, 0));
// calculate the drop show effect offset.
var shadowOffset = SystemParameters.DropShadow ? clientTopLeft.X - Left -
((WindowStyle == WindowStyle.None && ResizeMode < ResizeMode.CanResize) ? 0 : SystemParameters.BorderWidth) : 0;
// exclude left and right drop shadow area
int width = (int)(Width - 2 * shadowOffset);
// exclude bottom drop shadow area
int height = (int)(Height - shadowOffset);
using (Bitmap bmp = new Bitmap(width, height))
{
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.CopyFromScreen((int)(Left + shadowOffset),
(int)Top, 0, 0, bmp.Size);
}
bmp.Save("WindowCapture.png");
}

Wpf Text marquee behind other element

I built an messagebar, with an animated text,
see the .gif from the animation.
Like you can see the text "fly's" in the foreground and hides the placeholder. But I need the placeholder in the foreground.
My first idea was to change the region of the animation from
doubleAnimation.To = tbInfo.ActualWidth *-1;
to
doubleAnimation.To = boLogo.ActualWidth;
but the result looks like this: version with other animation area.
How can I set the placeholder in the foreground, so that the animation "fly's" behind it?
My XAML-Code
<Canvas x:Name="canMain" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Border x:Name="boLogo" Height="40" Background="Gray" Canvas.Left="0" Canvas.Top="-20">
<Button Content="Placeholder" Width="90" />
</Border>
<TextBlock x:Name="tbInfo" Visibility="Hidden" FontSize="32" FontWeight="Bold" Padding="5" HorizontalAlignment="Stretch" VerticalAlignment="Center"></TextBlock>
</Canvas>
and the code to show the window
public void ShowWindow(string str)
{
tbInfo.Text = str;
this.Height = 39;
this.Width = SystemParameters.WorkArea.Width;
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
this.Show();
TextMarquee(20);
}
private void TextMarquee(int duration)
{
double height = canMain.ActualHeight - tbInfo.ActualHeight;
tbInfo.Margin = new Thickness(0, height / 2, 0, 0);
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = canMain.ActualWidth;
doubleAnimation.To = tbInfo.ActualWidth * -1;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration));
tbInfo.BeginAnimation(Canvas.LeftProperty, doubleAnimation);
tbInfo.Visibility = Visibility.Visible;
}
Use the Panel.ZIndex:
<Canvas x:Name="canMain" >
<Border x:Name="boLogo" Panel.ZIndex="2">
<Button Content="Placeholder" Width="90" />
</Border>
<TextBlock x:Name="tbInfo" Panel.ZIndex="1"></TextBlock>
</Canvas>
https://msdn.microsoft.com/de-de/library/system.windows.controls.panel.zindex%28v=vs.110%29.aspx
Try the Grid.ZIndex:
<Grid x:Name="canMain" >
<Border x:Name="boLogo" Grid.ZIndex="2">
<Button Content="Placeholder" />
</Border>
<TextBlock x:Name="tbInfo" Grid.ZIndex="1"/>
</Grid>
Being ZIndex = "2" the most visible layer.

SetView in Windows Phone map with desired locations, margin and center point

I have added a map in my Windows Phone 8 application. Now I want is to view one desired point with a center point on the map.
XAML:
<Grid x:Name="ContentPanel" Grid.RowSpan="2">
<Grid.RowDefinitions>
<RowDefinition Height="68" />
<RowDefinition Height="1" />
<RowDefinition Height="65" />
<RowDefinition Height="1" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<maps:Map x:Name="map"
Grid.RowSpan="5"
Height="800" />
<Image Source="/Assets/Images/Pin.png" Width="35" Height="55"
VerticalAlignment="Center" HorizontalAlignment="Center"
Grid.RowSpan="5"
Canvas.ZIndex="15"/>
<Button Grid.Row="0" Content="Search" />
<Button Grid.Row="4" Content="Check" />
</Grid>
View Model C#
MapRectLocation zoomLocation = new MapRectLocation();
zoomLocation.CenterPoint = new Location() { lat = CenterLocation.Latitude, lng = CenterLocation.Longitude };
zoomLocation.Locationx = new Location();
zoomLocation.Locationx.Latitude = FirstLocation.Latitude;
zoomLocation.Locationx.Longitude= FirstLocation.Longitude;
// Calculate the other point for boundary
zoomLocation.Locationy= GetEqivalentPoint(CenterLocation, FirstLocation);
public Location GetEqivalentPoint(System.Device.Location.GeoCoordinate CenterLocation, Location location)
{
var dlat = CenterLocation.Latitude - location.lat;
var dlng = CenterLocation.Longitude - location.lng;
Location equiPoint = new Location();
equiPoint.lat = CenterLocation.Latitude + dlat;
equiPoint.lng = CenterLocation.Longitude + dlng;
return equiPoint;
}
XAML.cs Code:
List<GeoCoordinate> zoomBoundaries = new List<GeoCoordinate>();
zoomBoundaries.Add(new GeoCoordinate(mapViewLocation.Locationx.lat, mapViewLocation.Locationx.lng));
zoomBoundaries.Add(new GeoCoordinate(mapViewLocation.Locationy.lat, mapViewLocation.Locationy.lng));
map.SetView(LocationRectangle.CreateBoundingRectangle(zoomBoundaries), new Thickness(0, 150, 0, 300));
The map sets to desired zoom level to display that point but the problem is it does not keep the same centerpoint as earlier. I want to keep the Centerlocation as same and display FirstLocation point on the map. I am also setting margin in Setview as to keep that First location point above the 2 buttons that I have in my XAML code overlaying map.
Please let me know how to rectify this problem?
Try this:
void SetLoc()
{
MyMap.Layers.Clear();
try
{
// ... get the coordinates "myGeoCoordinate"
// Make my current location the center of the Map.
this.MyMap.Center = myGeoCoordinate;
this.MyMap.ZoomLevel = 12;
// Create a small circle to mark the current location.
Ellipse myCircle = new Ellipse();
myCircle.Fill = new SolidColorBrush(Colors.Blue);
myCircle.Height = 20;
myCircle.Width = 20;
myCircle.Opacity = 50;
// Create a MapOverlay to contain the circle.
MapOverlay myLocationOverlay = new MapOverlay();
myLocationOverlay.Content = myCircle;
myLocationOverlay.PositionOrigin = new Point(0.5, 0.5);
myLocationOverlay.GeoCoordinate = myGeoCoordinate;
// Create a MapLayer to contain the MapOverlay.
MapLayer myLocationLayer = new MapLayer();
myLocationLayer.Add(myLocationOverlay);
// Add the MapLayer to the Map.
MyMap.Layers.Add(myLocationLayer);
}
catch
{
}
}

Save didnt work the drawing WinRT

The application is running all good but when i'll go to save is like the margin move the picture and the drawing i do move too. What i'm doing wrong or what i need to do to fix that. I think is a geometry problem.
Xaml Code:
<Page
x:Class="DrawingWithMe.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DrawingWithMe"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Viewbox>
<Grid x:Name="Grid1" Height="768" Width="1366">
<Canvas x:Name="funnyCanvas" Background="White" Margin="162,10,254,42">
<Rectangle x:Name="Rectangle1" Fill="#FFF4F4F5" Stroke="Black"></Rectangle>
<Image x:Name="image" Source="Assets/Test.gif" Stretch="UniformToFill"/>
</Canvas>
</Grid>
</Viewbox>
<Page.BottomAppBar>
<AppBar x:Name="AppBar" Padding="10,0,10,0">
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Button Name="Save" Content="Save" VerticalAlignment="Top" Click="Save_Click_1" Grid.Column="1"></Button>
<Button Name="Erase" Content="Erase All" VerticalAlignment="Top" Click="Erase_Click_1" Grid.Column="2"></Button>
<Button x:Name="Copytoclipboard" Content="Copy To ClipBoard" VerticalAlignment="Top" Click="Copytoclipboard_Click_1"></Button>
<Button x:Name="Pastefrom" Content="Paste From ClipBoard" VerticalAlignment="Top" Click="Pastefrom_Click_1"></Button>
<Button x:Name="Recognizeword" Content="Recognize" VerticalAlignment="Top" Click="Recognizeword_Click_1"></Button>
</StackPanel>
</Grid>
</AppBar>
</Page.BottomAppBar>
</Page>
C# Code:
public async void TestingBlit()
{
var backgroundBmp = await BitmapFactory.New(1, 1).FromContent(new Uri(BaseUri, #"///Assets/Test.gif"));
//Image foreground
WriteableBitmap foregroundBmp;
using (InMemoryRandomAccessStream a = new InMemoryRandomAccessStream())
{
await _inkManager.SaveAsync(a);
a.Seek(0);
foregroundBmp = await new WriteableBitmap(1,1).FromStream(a);
}
// Combined
backgroundBmp.Blit(new Rect(0, 0, foregroundBmp.PixelWidth, foregroundBmp.PixelHeight), foregroundBmp,new Rect(0, 0, foregroundBmp.PixelWidth, foregroundBmp.PixelHeight), WriteableBitmapExtensions.BlendMode.ColorKeying);
// Save
Windows.Storage.Pickers.FileSavePicker save = new Windows.Storage.Pickers.FileSavePicker();
save.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
save.DefaultFileExtension = ".gif";
save.FileTypeChoices.Add("GIF", new string[] { ".gif" });
StorageFile filesave = await save.PickSaveFileAsync();
Guid encoderId = Windows.Graphics.Imaging.BitmapEncoder.PngEncoderId;
await WinRTXamlToolkit.Imaging.WriteableBitmapSaveExtensions.SaveToFile(backgroundBmp, filesave, encoderId);
//List<InkStroke> tmp = _inkManager.GetStrokes().ToList();
//tmp.RemoveAt(0);
//RenderStroke(tmp.ElementAt(0), Colors.SkyBlue, 10, 1);
SurfaceImageSource surfaceImageSource = new SurfaceImageSource((int)Rectangle1.ActualWidth, (int)Rectangle1.ActualHeight, true);
ImageBrush brush = new ImageBrush();
brush.ImageSource = image.Source;
Rectangle1.Fill = brush;
}
private void RenderStroke(InkStroke stroke, Color color, double width, double opacity = 1)
{
// Each stroke might have more than one segments
var renderingStrokes = stroke.GetRenderingSegments();
//
// Set up the Path to insert the segments
var path = new Windows.UI.Xaml.Shapes.Path();
path.Data = new PathGeometry();
((PathGeometry)path.Data).Figures = new PathFigureCollection();
var pathFigure = new PathFigure();
pathFigure.StartPoint = renderingStrokes.First().Position;
((PathGeometry)path.Data).Figures.Add(pathFigure);
//
// Foreach segment, we add a BezierSegment
foreach (var renderStroke in renderingStrokes)
{
pathFigure.Segments.Add(new BezierSegment()
{
Point1 = renderStroke.BezierControlPoint1,
Point2 = renderStroke.BezierControlPoint2,
Point3 = renderStroke.Position
});
}
// Set the general options (i.e. Width and Color)
path.StrokeThickness = width;
path.Stroke = new SolidColorBrush(color);
// Opacity is used for highlighter
path.Opacity = opacity;
funnyCanvas.Children.Add(path);
}
}
}
You put the content in a Viewbox, which will stretch it. You need to calculate the on-screen coordinates of your rectangle.
Give this a try.
var scalex = MyViewbox.GetScaleChildX();
var scaley = MyViewbox.GetScaleChildY();
SurfaceImageSource surfaceImageSource = new SurfaceImageSource((int)(scalex * Rectangle1.ActualWidth), (int)(scaley * Rectangle1.ActualHeight), true);
public static double GetChildScaleX(this Viewbox viewbox)
{
if (viewbox.Child == null)
throw new InvalidOperationException("Can't tell effective scale of a Viewbox child for a Viewbox with no child.");
var fe = viewbox.Child as FrameworkElement;
if (fe == null)
throw new InvalidOperationException("Can't tell effective scale of a Viewbox child for a Viewbox with a child that is not a FrameworkElement.");
if (fe.ActualWidth == 0)
throw new InvalidOperationException("Can't tell effective scale of a Viewbox child for a Viewbox with a child that is not laid out.");
return viewbox.ActualWidth / fe.ActualWidth;
}
GetChildScaleY is the same, but with Heights (taken from here).
(Make sure you name your Viewbox)
<Viewbox x:Name="MyViewbox">

Displaying Image in Circle in Windows Phone

I am creating a WP (7.1+8) app, that requires me to display images inside a circle ( as in Google+ ).
I found a solution that uses a GradientBrush to accomplish the task via following code:-
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri("http://url-of-the-image", UriKind.Absolute);
image.CacheMode = new BitmapCache();
image.Source = bitmapImage;
image.Stretch = Stretch.UniformToFill;
image.VerticalAlignment = System.Windows.VerticalAlignment.Center;
//Setting up the mask
RadialGradientBrush opacityMask = new RadialGradientBrush();
GradientStop gs1 = new GradientStop();
GradientStop gs2 = new GradientStop();
GradientStop gs3 = new GradientStop();
gs1.Color = Color.FromArgb(255, 0, 0, 0);
gs1.Offset = 0.0;
gs2.Color = Color.FromArgb(255, 0, 0, 0);
gs2.Offset = 0.999;
gs3.Color = Color.FromArgb(0, 0, 0, 0);
gs3.Offset = 1.0;
opacityMask.GradientStops.Add(gs1);
opacityMask.GradientStops.Add(gs2);
opacityMask.GradientStops.Add(gs3);
image.OpacityMask = opacityMask;
I want to know that what will be the performance impact if i needed to do this on large number of images, say 50.
Use clipping to display partial area of a control.
<Image Source="YouImage.jpg">
<Image.Clip>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50" />
</Image.Clip>
</Image>
Change the Center, RadiusX and RadiusY to your convenience.
Use the following code snippet for your requirement.
<Ellipse Height="300" Width="300">
<Ellipse.Fill>
<ImageBrush ImageSource="images/WmDev.jpg" AlignmentX="Center" AlignmentY="Center" />
</Ellipse.Fill>
</Ellipse>
Hope it Helps.
This question is already answered still if you want to see it in more detail then you could have a look here
The XAML solution will be,
<Image Source=”{Binding Converter={StaticResource ContactPictureConverter}}” Width=”48″ Height=”48″ Stretch=”Fill”
>
<Image.Clip>
<EllipseGeometry Center=”24,24″ RadiusX=”24″ RadiusY=”24″ />
</Image.Clip>
</Image>

Categories

Resources