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>
Related
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" />
How can I convert this code part from XAML to C# code?
<ComboBoxItem x:Name="cmbItemDashDot1">
<Viewbox>
<Image Height="18" Width="70">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,9" EndPoint="38,9" />
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="1" DashStyle="{x:Static DashStyles.DashDot}"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Viewbox>
</ComboBoxItem>
I can not find analogies for some elements.
Or How can I draw a line in ComboBoxItem programmatically?
Try this code
Image img = new Image();
GeometryDrawing gDrwing = new GeometryDrawing();
gDrwing.Brush = Brushes.Black;
LineGeometry lineGeo = new LineGeometry();
lineGeo.StartPoint = new Point(0, 9);
lineGeo.EndPoint = new Point(38, 9);
Pen pen = new Pen();
pen.Brush = Brushes.Black;
pen.Thickness = 1;
pen.DashStyle = DashStyles.DashDot;
gDrwing.Geometry = lineGeo;
gDrwing.Pen = pen;
DrawingImage geometryImage = new DrawingImage(gDrwing);
img.Source = geometryImage;
Viewbox vb = new Viewbox();
vb.Child = img;
comboBox1.Items.Add(vb);
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">
I am trying to Create anImage overlay, same size as the lower Image with transparent sections. The problem I am having is the transparent sections of the overlay show as black in the canvas or are never really set to transparent in the first place.
The overlay is a property of the view model:
this.Logger.Trace("overlay get start");
Bitmap bmp = new Bitmap(this.imageWidth, this.imageHeight, PixelFormat.Format8bppIndexed);
System.Drawing.Imaging.ColorPalette myPalette = bmp.Palette;
for (int x = 0; x < 256; x++)
{
myPalette.Entries[x] = System.Drawing.Color.FromArgb(x, x, x);
}
bmp.Palette = myPalette;
// Create a BitmapData and Lock all pixels to be written
BitmapData bmpData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly,
bmp.PixelFormat);
for (int iRow = 0; iRow < this.imageHeight; iRow++)
{
Marshal.Copy(this.overlay, (iRow * this.imageWidth), bmpData.Scan0 + (iRow * bmpData.Stride), this.imageWidth);
}
// Marshal.Copy(this._overlay, 0, bmpData.Scan0, this.imageWidth * this.imageHeight);//this._overlay.Length);
// Unlock the pixels
bmp.UnlockBits(bmpData);
bmp.MakeTransparent(Color.FromArgb(255, 255, 255));
bmp.MakeTransparent(bmp.GetPixel(0, 0));
bmp.MakeTransparent(bmp.GetPixel(1, 1));
this.Logger.Trace("overlay get end");
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
BitmapImage bImg = new System.Windows.Media.Imaging.BitmapImage();
bImg.BeginInit();
bImg.StreamSource = new MemoryStream(ms.ToArray());
bImg.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
bImg.CacheOption = BitmapCacheOption.Default;
bImg.EndInit();
ms.Close();
imagesRec++; //for debug purposes
return bImg;
Here is the XAML:
<StackPanel Grid.Column="1" >
<Canvas DragDrop:DragDropManager.DropTargetAdvisor="{StaticResource targetAdvisor1}" Name="CanvasObj" >
<Image x:Name="CameraImage" Source="{Binding CameraImage}" VerticalAlignment="Top" HorizontalAlignment="Center" ></Image>
<Image x:Name="Overlay" Source="{Binding Overlay}" VerticalAlignment="Top" HorizontalAlignment="Center" ></Image>
</Canvas>
</StackPanel>
There is no need to do that at all; use a PNG format image with the alpha layer already filled in. The rest will "Just work".
Why does Storyboard.SetTargetName works but Storyboard.SetTarget does not?
Here xaml -
<Grid Grid.Row="0" ClipToBounds="True">
<X:SmartContentControl x:Name="smartContent" Content="{Binding Path=MainContent}" ContentChanging="smartContent_ContentChanging">
<X:SmartContentControl.RenderTransform>
<TranslateTransform x:Name="translateTransformNew" X="0" Y="0"/>
</X:SmartContentControl.RenderTransform>
</X:SmartContentControl>
<ContentControl Content="{Binding ElementName=smartContent, Path=LastImage}">
<ContentControl.RenderTransform>
<TranslateTransform x:Name="translateTransformLast" X="0" Y="0"/>
</ContentControl.RenderTransform>
</ContentControl>
</Grid>
Here C#
private void smartContent_ContentChanging(object sender, RoutedEventArgs e)
{
Storyboard storyBoard = new Storyboard();
DoubleAnimation doubleAnimation1 = new DoubleAnimation(0.0, -smartContent.RenderSize.Width, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
DoubleAnimation doubleAnimation2 = new DoubleAnimation(smartContent.RenderSize.Width, 0.0, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
doubleAnimation1.AccelerationRatio = 0.5;
doubleAnimation2.DecelerationRatio = 0.5;
storyBoard.Children.Add(doubleAnimation1);
storyBoard.Children.Add(doubleAnimation2);
Storyboard.SetTarget(doubleAnimation1, this.translateTransformLast); //--- this does not work
//Storyboard.SetTargetName(doubleAnimation1, "translateTransformLast"); -- this works
Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath(TranslateTransform.XProperty));
Storyboard.SetTarget(doubleAnimation2, this.translateTransformNew);//--- this does not work
//Storyboard.SetTargetName(doubleAnimation2, "translateTransformNew"); -- this works
Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath(TranslateTransform.XProperty));
if (smartContent.LastImage != null)
storyBoard.Begin();
}
I found answer here!
Why don't these animations work when I'm using a storyboard?
Storyboard cant animate TranslateTransform, since it is not UIElement.
This is how i do it now! :)
Storyboard.SetTarget(doubleAnimation1, this.lastImage);
Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath("RenderTransform.(TranslateTransform.X)"));
Storyboard.SetTarget(doubleAnimation2, this.smartContent);
Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath("RenderTransform.(TranslateTransform.X)"));