Using maui and SkiaSharp to crop an image for a user profile image. unable to center correctly

72 Views Asked by At

I have an image with an overlaid Ellipse target that I want to create another image from. The purpose is to create a user profile image. Can pan in all directions and zoom in/out.

I can create an image but not in the correct position. I‘m struggling with getting the center coordinates. The yellow Ellipse is the target area for the user profile image to be taken from.

When in this position enter image description here

I get this as the saved image enter image description here

When i move to the top enter image description here

I get this enter image description here

This is my xaml

<Grid>
            <!-- Image and Yellow Circle -->
            <Image x:Name="image" Source="{Binding Img}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">

            </Image>

            <Ellipse x:Name="MyEllipse" WidthRequest="150" HeightRequest="150" HorizontalOptions="Center" VerticalOptions="Center" Stroke="Yellow" StrokeThickness="5" Fill="Transparent"/>

            
            <!-- Move Image Buttons -->
            <StackLayout Orientation="Vertical" HorizontalOptions="End" VerticalOptions="End">
                <Button Clicked="OnZoomInClicked" Text="Zoom In" />
                <!-- Zoom Out Button -->
                <Button Clicked="OnZoomOutClicked" Text="Zoom Out" HorizontalOptions="End" />

                <Button Text="Pick Photo" Command="{Binding PickPickCommand}" />
                <Button Text="Save Image" Clicked="OnSaveImageClicked" />
                <Button Pressed="OnMoveUpPressed" Released="OnMoveReleased" Text="Up" />
                <Button Pressed="OnMoveDownPressed" Released="OnMoveReleased" Text="Down" />
                <Button Pressed="OnMoveLeftPressed" Released="OnMoveReleased" Text="Left" />
                <Button Pressed="OnMoveRightPressed" Released="OnMoveReleased" Text="Right" />
            </StackLayout>
        </Grid>

This is the .xaml.cs code behind for OnSaveImageClicked

(double xEll, double yEll) = GetEllipseCenterRelativeToImage();

        int x = (int)Math.Round(xEll);
        int y = (int)Math.Round(yEll);

        int width = 370;
        int height = 370;

        string dur = VM.ImgPath;

        byte[] fileBytes = File.ReadAllBytes(dur);

        MemoryStream streamX = new MemoryStream(fileBytes);
        SKBitmap bm = SKBitmap.Decode(streamX);

        using SkiaSharp.SKPixmap skPixmap = new SkiaSharp.SKPixmap(bm.Info, bm.GetPixels());
        SkiaSharp.SKPixmap subset = skPixmap.ExtractSubset(new SkiaSharp.SKRectI(x, y, x + width, y + height));
        SkiaSharp.SKData skData = subset.Encode(SkiaSharp.SKEncodedImageFormat.Png, 100);
        System.IO.MemoryStream stream = new System.IO.MemoryStream();
        skData.SaveTo(stream);

        var item = Task.Run(async () => await ImageService.ProcessUserImgFile(stream));

GetEllipseCenterRelativeToImage() gets the center points which is not working. Below is the GetEllipseCenterRelativeToImage code.

private (double x, double y) GetEllipseCenterRelativeToImage()
    {
        // Get the position and size of the ellipse
        double ellipseX = MyEllipse.X;
        double ellipseY = MyEllipse.Y;
        double ellipseWidth = MyEllipse.Width;
        double ellipseHeight = MyEllipse.Height;

        // Calculate the visible width and height of the image
        double visibleWidth = image.Width * image.Scale;
        double visibleHeight = image.Height * image.Scale;

        // Calculate the center coordinates of the visible portion of the image
        double imageCenterX = image.TranslationX + (visibleWidth / 2);
        double imageCenterY = image.TranslationY + (visibleHeight / 2);

        // Calculate the top-left corner of the visible portion of the image
        double topLeftX = imageCenterX - (visibleWidth / 2);
        double topLeftY = imageCenterY - (visibleHeight / 2);

        // Adjust the position of the ellipse relative to the top-left corner of the visible portion of the image
        double ellipseCenterXRelativeToImage = ellipseX - topLeftX + (ellipseWidth / 2);
        double ellipseCenterYRelativeToImage = ellipseY - topLeftY + (ellipseHeight / 2);
       
        return (ellipseCenterXRelativeToImage, ellipseCenterYRelativeToImage);
    }

Would be very grateful to anyone who could help me find a way to get the correct center coordinates.

I have tired changing the values in GetEllipseCenterRelativeToImage. Am also aware that zooming in and out will also have an effect on the position of the new image

0

There are 0 best solutions below