I have a Xamarin MediaElement:
<xct:MediaElement x:Name="mediaElement" Source="video.mp4" AutoPlay="True" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Aspect="AspectFill" ShowsPlaybackControls="False" PropertyChanged="mediaElement_PropertyChanged" MediaOpened="mediaElement_MediaOpened"></xct:MediaElement>
Which I can zoom and pan up/down/left/right.
After zooming then panning, the anchor for the next zoom stays at (.5, .5); the middle of the video.
I need it to zoom in on the center of the video based on where the video is on the screen after the zoom/pan is performed.
For example:
My screen is 788x397 (landscape).
The video fits the screen: AspectFill
The video is then zoomed (mediaElement.Scale) to 2.
The video is then panned to the right (mediaElement.TranslationX) 100px.
At this point, when zooming, I need it to zoom in/out at the panned/scaled location, which is no longer (.5, .5).
I tried to calculate the new center point based on the translation; ex. mediaElement.AnchorX = .6, mediaElement.AnchorY = .5, but the zoom did some wierd things as the calculation of AnchorX/AnchorY was updated while zooming.
I tried not changing the AnchorX/AnchorY at all, and forcing (.5, .5), but both these solutions zoomed based on the center of the video, and not the center of the video in relation to where it is on the screen.
Any insight would be greatly appreciated.
Here is the C# and XAML code for each Xamarin.Slider:
// zoom
private void sliderZoom_ValueChanged(object sender, EventArgs e) {
double zoom = ((sender as Slider).Value / 10) + 1;
mediaElement.Scale = zoom;
}
<Slider x:Name="sliderZoom"
Maximum="100"
Minimum="0"
HorizontalOptions="CenterAndExpand"
WidthRequest="150"
HeightRequest="30"
BackgroundColor="Transparent"
ValueChanged="sliderZoom_ValueChanged" />
// pan horizontal
private void sliderPanHorizontal_ValueChanged(object sender, EventArgs e)
{
double pan = (((mediaElement.Scale * Content.Width) - Content.Width)/2) * ((sender as Slider).Value / 100);
mediaElement.TranslationX = pan;
}
<Slider x:Name="sliderPanHorizontal"
Maximum="100" Minimum="-100" Value="0"
HorizontalOptions="CenterAndExpand"
WidthRequest="100" HeightRequest="30"
Rotation="180"
BackgroundColor="Transparent" ValueChanged="sliderPanHorizontal_ValueChanged" />
// pan vertical
private void sliderPanVertical_ValueChanged(object sender, EventArgs e)
{
double pan = (((mediaElement.Scale * Content.Height) - Content.Height) / 2) * ((sender as Slider).Value / 100);
mediaElement.TranslationY = pan;
}
<Slider x:Name="sliderPanVertical"
Maximum="100" Minimum="-100" Value="0"
HorizontalOptions="CenterAndExpand"
WidthRequest="100" HeightRequest="30"
BackgroundColor="Transparent" ValueChanged="sliderPanVertical_ValueChanged" />
Related
I have a Xaml page with a grid with relative heights
<RowDefinition Height="1*">
<RowDefinition Height="2*">
<RowDefinition Height="3*">
Now on the middle row (And i don't know it's exact height since it scales with the display size) I want to have a circular image. Since I have not set a heightrequest / widthrequest for the image I think I need to bind it to actual height.
I tried a lot of things resulting in my 'latest effort which is the following code but still does not give the desired result
<!-- try 1 -->
<yummy:PancakeView BackgroundColor="Aqua" CornerRadius="{Binding Source={RelativeSource Self}, Path=ActualHeight, Converter={converters:PercentageConverter}, ConverterParameter='0,5'}" IsClippedToBounds="True" BorderColor="Black" BorderThickness="4">
<Image Source="{Binding NarrationImage}" ></Image>
</yummy:PancakeView>
<!-- try 2 -->
<Grid x:Name="RefGrid" WidthRequest="1"></Grid>
<Frame
HeightRequest="{Binding Path=ActualHeight, Source={x:Reference RefGrid}}"
WidthRequest="{Binding Path=ActualHeight, Source={x:Reference RefGrid}}"
CornerRadius="{Binding Path=ActualHeight, Source={x:Reference RefGrid}}"
IsClippedToBounds="True" Padding="0" VerticalOptions="CenterAndExpand">
<Image Source="{Binding NarrationImage}" Aspect="AspectFill"></Image>
</Frame>
Since you had set the Height of Row as * . The real size of Frame in runtime depend on the size of Grid . In your case , the Height of Frame equals 1/3 of the Grid and the Width equals the width of the Grid .
If you want to get the value of them .You could create a custom Frame .And rewrite the method OnSizeAllocated
using Xamarin.Forms;
namespace App10
{
public class MyFrame:Frame
{
protected override void OnSizeAllocated(double width, double height)
{
if(width>0&&height>0)
{
var size =width<height ? width: height ;
CornerRadius = (float)size / 2;
}
base.OnSizeAllocated(width, height);
}
public MyFrame()
{
SizeChanged += MyFrame_SizeChanged;
}
private void MyFrame_SizeChanged(object sender, EventArgs e)
{
var width = this.Width;
var height = this.Height;
if (width > 0 && height > 0)
{
var size = width < height ? width : height;
CornerRadius = (float)size / 2;
}
}
}
}
This method will been invoked multi times when it been first added to the parent view. The last time it will return the current size . You can do something you want .
How can I set the size of the image inside of a list view. Currently I have several lists that have icons but I don't see any options for changing the aspect ratio or size of the image so it just gets blown up to the height of the list item.
all the images are from the Drawable folder
var cell = new DataTemplate(typeof(MenuTextCell));
cell.SetBinding(TextCell.TextProperty, "Title");
cell.SetBinding(ImageCell.ImageSourceProperty, "IconSource");
cell.SetValue(BackgroundColorProperty, Color.Transparent);
cell.SetValue(TextCell.TextColorProperty, Color.FromHex("262626"));
I am using a custom renderer
public class MenuTextCellRenderer : ImageCellRenderer
{
protected override View GetCellCore (Cell item, View convertView, ViewGroup parent, Context context)
{
var cell = (LinearLayout)base.GetCellCore (item, convertView, parent, context);
cell.SetPadding(20, 10, 0, 10);
cell.DividerPadding = 50;
var div = new ShapeDrawable();
div.SetIntrinsicHeight(1);
div.Paint.Set(new Paint { Color = Color.FromHex("b7b7b7").ToAndroid() });
if (parent is ListView)
{
((ListView)parent).Divider = div;
((ListView)parent).DividerHeight = 1;
}
var icon = (ImageView)cell.GetChildAt(0);
var label = (TextView)((LinearLayout)cell.GetChildAt(1)).GetChildAt(0);
label.SetTextColor(Color.FromHex("262626").ToAndroid());
label.TextSize = Font.SystemFontOfSize(NamedSize.Large).ToScaledPixel();
label.TextAlignment = TextAlignment.Center;
label.Text = label.Text.ToUpper();
var secondaryLabel = (TextView)((LinearLayout)cell.GetChildAt(1)).GetChildAt(1);
secondaryLabel.SetTextColor(Color.FromHex("262626").ToAndroid());
secondaryLabel.TextSize = Font.SystemFontOfSize(NamedSize.Large).ToScaledPixel();
label.TextAlignment = TextAlignment.Center;
return cell;
}
You are now dealing with an Android ImageView.
You have your reference via var icon = (ImageView)cell.GetChildAt(0).
You can now customize it via methods such as .setScaleType() for aspect ratio related, and use .layout() to change the position / size.
Try something like this on your ListView.ItemTemplate, instead of using the imagecell. You can also write your custom cell.
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" Orientation="Horizontal" Padding="10">
<Image Aspect="AspectFill" HeightRequest ="20" WidthRequest="20" Source="{Binding IconSource}" />
<Label Text="{Binding Title}" YAlign="Center" Font="Medium" />
</StackLayout>
</ViewCell>
I have put an image in the scrollview and canvas as xaml below:
<ScrollViewer x:Name="scroll" HorizontalAlignment="Center" VerticalAlignment="Center" Width="340" Height="480">
<Canvas x:Name="canvas" HorizontalAlignment="Center" VerticalAlignment="Center" Width="340" Height="480" Background="Blue">
<Image x:Name="photo" Stretch="Fill" HorizontalAlignment="Center" VerticalAlignment="Center" ManipulationMode="All" Width="340" Height="480">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
</Canvas>
</ScrollViewer>
After that, I created a button to load and crop the image:
private async void btnCrop_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
fileOpenPicker.FileTypeFilter.Add(".jpg");
fileOpenPicker.FileTypeFilter.Add(".jpeg");
fileOpenPicker.FileTypeFilter.Add(".png");
fileOpenPicker.FileTypeFilter.Add(".bmp");
file = await fileOpenPicker.PickSingleFileAsync();
if (file != null)
{
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
BitmapTransform transform = new BitmapTransform();
BitmapBounds bounds = new BitmapBounds();
bounds.X = bounds.Y = 0;
bounds.Height = bounds.Width = 150;
transform.Bounds = bounds;
PixelDataProvider pix = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
byte[] pixels = pix.DetachPixelData();
WriteableBitmap cropBmp = new WriteableBitmap(340, 480);
Stream pixStream = cropBmp.PixelBuffer.AsStream();
pixStream.Write(pixels, 0, 150 * 150 * 4);
photo.Source = cropBmp;
}
}
The image has been crop and displayed successful. But when I zoom my image, I just want crop the image within the canvas instead of hard code. The code above is hard code the BitmapBounds width and height. How do I solve it? Thanks
Please help me how to move the image as automatically to specific x y position by using of animation class in windows phone 7, i have tried by Point animation class but this is not working for image control but working for object, so please tell me what kind of animation class should i use for moving image in windows phone 7
and my code is
XAML
</PointAnimation>
</Storyboard>
</Canvas.Resources>
<Image Source="qq.jpg" Width="200" Height="100" x:Name="MyImage" Canvas.Left="10" Canvas.Top="10" />
</Canvas>
</Grid>
c#
private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Point mypoint = new Point();
mypoint.X = 10;
mypoint.Y = 200;
MyPointAnimation.To = mypoint;
myStoryboard.Begin();
}
you can do something like that :
<Image x:Name="myImage"
Canvas.Left="10"
Canvas.Top="10"
Width="200"
Height="100"
Source="/Assets/qq.jpg">
<Image.RenderTransform>
<TranslateTransform />
</Image.RenderTransform>
</Image>
and then in code behind :
TranslateTransform trans = myImage.RenderTransform as TranslateTransform;
DoubleAnimation anima1 = new DoubleAnimation();
anima1.To = 150;
Storyboard.SetTarget(anima1, trans);
Storyboard.SetTargetProperty(anima1, new
PropertyPath(TranslateTransform.XProperty));
// Create storyboard, add animation, and fire it up!
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(anima1);
storyboard.Begin();
Is there a scrollView in phone7?
I have this code
private void button8_Click(object sender, RoutedEventArgs e)
{
for (int i=0; i<23; i++) {
Button btn = new Button() {
Content="newbutton "+i,
HorizontalAlignment =HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(0, 20+(i*60), 0, 0),
};
btn.Click += new RoutedEventHandler(btn_click);
ContentPanel.Children.Add(btn);
}
}
to add 23 buttons to my screen, what is the way to scrolling down the page to show all of the 23 buttons?
I'm assuming ContentPanel is a StackPanel.
In XAML:
<ScrollViewer>
<StackPanel x:Name="ContentPanel" />
</ScrollViewer>
You can use the ScrollViewer.ScrollToVerticalOffset method to scroll to the end of the page.
However, if you have other UIElements above the ScrollViewer those will still occupy the top of your screen with only the section occupied by the ScrollViewer being scrolled. To prevent that you'll have to have all the UIElements, including ContentPanel, be placed in the ScrollViewer.