0

I am coding a cross platform app and currently working on where users can choose images or videos up to 10 using Xamarin.MediaGallery NuGet Package. This line, var results = await MediaGallery.PickAsync(10, MediaFileType.Image, MediaFileType.Video);, let's me choose both Images and Videos up to 10 and the code below takes the images, convert each into a byte array, and add them to an empty byte list and send it to another page. What I can confirm is that when a user selects, let's say, 5 pictures from their gallery, each picture is successfully converted into a byte and sent it to another page where that page displays the selected pictures.

 private async void PickFromLibrary(object sender, EventArgs e)
        {
            var results = await MediaGallery.PickAsync(10, MediaFileType.Image, MediaFileType.Video);

            try
            {
                if (results.Files == null)
                    return;
                List<byte[]> byteList = new List<byte[]>();
                foreach (var media in results.Files)
                {
                    photoPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "rotated_photo.jpg");
                    var selectedMedia = media.OpenReadAsync().Result;
                    using (var memoryStream = new MemoryStream())
                    {
                        await selectedMedia.CopyToAsync(memoryStream);

                        // skipped code. Rotate the image by 90 degrees to the right

                        byte[] rotatedImageBytes = File.ReadAllBytes(photoPath);

                        byteList.Add(rotatedImageBytes);
                    }
                    File.Delete(photoPath);
                }
                await Navigation.PushAsync(new EditPostPage(userId, textId, byteList));
            }
            catch (OperationCanceledException)
            {
                await Navigation.PopAsync();
            }
            catch (Exception ex)
            {
                await DisplayAlert("Error", $"Failed selecting medias: {ex.Message}", "OK");
            }

        }

With the code above, this is the XAML code in EditPostPage that shows the images in CarouselView. I didn't implement any other code like MediaElement to display a video yet.

<CarouselView x:Name="imageCarousel" IndicatorView="IndicatorView">
             <CarouselView.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding}" Aspect="AspectFill" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
                            RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}" />
                </DataTemplate>
            </CarouselView.ItemTemplate>
        </CarouselView>

And below is the back end code where it takes the byte list and convert it back to images.

public EditPostPage(int userId, int textId, List<byte[]> byteList)
        {
            InitializeComponent();
            this.userId = userId;
            this.textId = textId;
            this.byteImage = byteList;

            Appearing += (sender, e) =>
            {
                imageCarousel.ItemsSource = byteImage.Select(bytes => ImageSource.FromStream(() => new MemoryStream(bytes)));
                if (byteImage.Count <= 1)
                {
                    imageCarousel.IsSwipeEnabled = false;
                }
            };
        }

What I am struggling is that now that the users can successfully select images and the EditPostPage shows the images, I want the users to be able to select videos and the videos show up on EditPostPage. I did use var results = await MediaGallery.PickAsync(10, MediaFileType.Image, MediaFileType.Video); so users can select videos. But there are two things that I can't figure out.

  1. I don't know if the PickFromLibrary method will also turn the selected videos into a byte array and send it to EditPostPage.

  2. How will I modify EditPostPage so if the user selected a video, it shows the video, if the user selected images, it shows the images. I want to implement a code where the code determines if the selected media is an image or a video and act accordingly. That is, if user selects an image, it displays the image, if user selects a video, it displays the video. Even though I read MediaGallery doc in GitHub I can't figure out how to distinguish whether the user selected an image or a video. https://github.com/dimonovdd/Xamarin.MediaGallery

I was considering put something like the following code where I implement IsVisible function and make it true or false depending on the media type. But How would I figure out if the media type the user selected is an image or a video?

<CarouselView x:Name="imageCarousel" IndicatorView="IndicatorView" IsVisible="{Binding IsImageCarouselVisible}">
             <CarouselView.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding}" Aspect="AspectFill" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
                            RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}" />
                </DataTemplate>
            </CarouselView.ItemTemplate>
        </CarouselView>
        <xyt:MediaElement x:Name="videoPlayer" IsVisible="{Binding IsVideoPlayerVisible}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
                        RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}" />
4
  • IMediaFile contains an Extension, ContentType, and Type fields that should all allow you to distinguish a video from an image. Commented May 22, 2023 at 14:32
  • what is the purpose of converting to a byte[] instead of just passing the IMediaFile? Commented May 22, 2023 at 14:33
  • @Jason I used byte[] since it offers a more straightforward and generic approach. There isn't really a specific reason why I chose byte[]. I've never used IMediaFile before and have no knowledge. Is there a website or a doc I can view? Thank you. Commented May 22, 2023 at 14:40
  • it is in the code of the repo you linked to Commented May 22, 2023 at 14:43

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.