How I can get image size after loading?

kostya_kostya_ Member ✭✭

I need to wait for loading image and then return width and height to the main thread. I tried FFImageLoading but can't understand how return size to main thread because finally I need to return View. Because of void delegate for event imageGlassLiquid.Success I can't return Task. I thought about something like this:

CachedImage imageGlassLiquid = new CachedImage
{
      Source = cocktailRecipe.ConstructCocktailGlassLiquidPath,                
};
Await imageGlassLiquid.Success += (sender, e) =>
{
       var h = e.ImageInformation.OriginalHeight;
       var w = e.ImageInformation.OriginalWidth;
 };
make something with h and w in main code

Answers

  • JarvanJarvan Member, Xamarin Team Xamurai

    Using ImageInformation.OriginalHeight and ImageInformation.OriginalWidth can help you get the original size of the image.
    What's the problem now? If you are facing some issues while implementing, try to post the particular error with the corresponding codes here.

  • kostya_kostya_ Member ✭✭

    I need to get height and width of imageGlassLiquid to make cocktail image that consist of some parts (liquid, glass, ice, accessorise and other). Liquid is first image, second image will have position relative to liquid.
    My code:

    ``
    public View ConstructCocktail(CocktailCPMP cocktailRecipe, double heightOfFrameWithPhoto, CocktailsPage cocktailPage)
    {
        var relLayout = new RelativeLayout();
        string glassId = cocktailRecipe.GlassId;
        Frame consrtuctCocktailFrame = new Frame
        {
            CornerRadius = 10,
            Padding = paddingInCocktailConstructMainFrame,
            HasShadow = false,
            IsClippedToBounds = true,
            HeightRequest = heightOfFrameWithPhoto,
            BackgroundColor = Color.Transparent
        };
    
       consrtuctCocktailFrame.Content = relLayout;
    
        //liquid
        CachedImage imageGlassLiquid = new CachedImage();
        imageGlassLiquid.Success += (sender, e) =>
        {
            var h = e.ImageInformation.OriginalHeight;
            var w = e.ImageInformation.OriginalWidth;
    
            var r = w / h;
        };
        imageGlassLiquid.Source = cocktailRecipe.ConstructCocktailGlassLiquidPath;
        //color of liquid
        imageGlassLiquid.Transformations = new List<FFImageLoading.Work.ITransformation>
        {
            new FFImageLoading.Transformations.TintTransformation(){ HexColor=cocktailRecipe.HexColor, EnableSolidColor= true   }
        };
    
        switch (glassId)
        {
            //small size for small glasses
            case "2":
            case "7":
            case "10":
            case "12":
            case "16":
                relLayout.Children.Add(imageGlassLiquid,
                    xConstraint: Constraint.RelativeToParent((parent) =>
                    {
            //!!!!!!!!!! here the problem: width or height  of imageGlassLiquid =  -1
                        return parent.Width * 0.5 - imageGlassLiquid.Width * 0.5;
                    }),
                    yConstraint: Constraint.RelativeToParent((parent) =>
                    {
                        return parent.Height * 0.5 - imageGlassLiquid.Height * 0.4;
                    }),
                    widthConstraint: Constraint.RelativeToParent((parent) =>
                    {
                        return parent.Width * smallGlassRatio;
                    }),
                    heightConstraint: Constraint.RelativeToParent((parent) =>
                    {
                        return parent.Height * smallGlassRatio;
                    })
                    );
                break;
    
            default:
                relLayout.Children.Add(imageGlassLiquid,
                    xConstraint: Constraint.RelativeToParent((parent) =>
                    {
                        return parent.Width * 0.5 - imageGlassLiquid.Width * 0.5;
                    }),
                    yConstraint: Constraint.RelativeToParent((parent) =>
                    {
                        return parent.Height * 0.5 - imageGlassLiquid.Height * 0.4;
                    }));
                break;
        }
    
        // ice
        if (cocktailRecipe.ConstructCocktailIce1Enabled)
        {
            CachedImage imageIce1 = new CachedImage
            {
                Source = cocktailRecipe.ConstructCocktailIce1Path
            };
    
            imageIce1.Success += (sender, e) =>
            {
                var h = e.ImageInformation.OriginalHeight;
                var w = e.ImageInformation.OriginalWidth;
                Console.WriteLine("Dimensions " + " " + w);
            };
            switch (glassId)
            {
                //for low glasses needs small size
            //!!!!!!!!!! here the problem: width or height  of imageGlassLiquid =  -1
                case "2":
                case "7":
                case "10":
                case "12":
                case "16":
                    relLayout.Children.Add(imageIce1,
                        xConstraint: Constraint.RelativeToView(imageGlassLiquid, (parent, view) =>
                        {
                            return view.X + view.Width * 0.5 - imageIce1.Width * 0.5;
                        }),
                        yConstraint: Constraint.RelativeToView(imageGlassLiquid, (parent, view) =>
                        {
                            return view.Y + view.Height * 0.5 - imageIce1.Height * 0.5;
                        }),
                        widthConstraint: Constraint.RelativeToParent((parent) =>
                        {
                            return parent.Width * smallGlassRatio;
                        }),
                        heightConstraint: Constraint.RelativeToParent((parent) =>
                        {
                            return parent.Height * smallGlassRatio;
                        }));
                    break;
                default:
                    relLayout.Children.Add(imageIce1,
                        xConstraint: Constraint.RelativeToView(imageGlassLiquid, (parent, view) =>
                        {
                            return view.X + view.Width * 0.5 - imageIce1.Width * 0.5;
                        }),
                        yConstraint: Constraint.RelativeToView(imageGlassLiquid, (parent, view) =>
                        {
                            return view.Y + view.Height * 0.5 - imageIce1.Height * 0.5;
                        }));
                    break;
    
            }
        }
    
        return consrtuctCocktailFrame; 
    }
    ``
    
  • JarvanJarvan Member, Xamarin Team Xamurai
    edited October 10

    You should initilize the 'h' and 'w' as global variables to get the value, or move the 'make something' code to Success method.
    1.

    CachedImage imageGlassLiquid = new CachedImage
    {
          Source = cocktailRecipe.ConstructCocktailGlassLiquidPath,                
    };
    Await imageGlassLiquid.Success += (sender, e) =>
    {
           var h = e.ImageInformation.OriginalHeight;
           var w = e.ImageInformation.OriginalWidth;
    
        //make something with h and w in main code
     };
    

    2.

    double h = 0;
    double w = 0;
    
    CachedImage imageGlassLiquid = new CachedImage
    {
          Source = cocktailRecipe.ConstructCocktailGlassLiquidPath,                
    };
    Await imageGlassLiquid.Success += (sender, e) =>
    {
           h = e.ImageInformation.OriginalHeight;
           w = e.ImageInformation.OriginalWidth;
     };
    //make something with h and w in main code
    
  • kostya_kostya_ Member ✭✭

    @Jarvan said:

    2.
    

    double h = 0;
    double w = 0;

    CachedImage imageGlassLiquid = new CachedImage
    {
    Source = cocktailRecipe.ConstructCocktailGlassLiquidPath,
    };
    Await imageGlassLiquid.Success += (sender, e) =>
    {
    h = e.ImageInformation.OriginalHeight;
    w = e.ImageInformation.OriginalWidth;
    };
    //make something with h and w in main code
    ```

    First case doesnt suit for me because I need return a View value from ConstructCocktail.
    Second variant is better, but how I can await imageGlassLiquid.Success event? I tried code with your correction but height was zero and only after event has fired then height became true value (and at this moment calculation of position other images was made incorrectly).

  • JarvanJarvan Member, Xamarin Team Xamurai
    edited October 11

    'Success event not fire' is a known issue and it seems not a good way to solved that. Try to get the image size on each platform , then call the method and get the value using DependencyService.

    For Android you can do something like:

    using (var opt = new BitmapFactory.Options() { InJustDecodeBounds = true })
    using (BitmapFactory.DecodeFile(FilePath, opt))
    {
        var width = opt.OutWidth;
        var height = opt.OutHeight;
    }
    

    For IOS:

    public static CGSize GetImageSizeFromPath(string FilePath)
    {
        using (var src = CGImageSource.FromUrl(NSUrl.FromFilename(FilePath)))
        {
            var imgStatus = src.GetStatus(0);
            var options = new CGImageOptions() { ShouldCache = false };
    
            // MAKE SURE to provide an index or else the PixelWidth and PixelHeight will be NULL
            var properties = src.GetProperties(0, options);
    
            return new CGSize((int)properties.PixelWidth, (int)properties.PixelHeight);
        }
    }
    var imgSize = Methods.GetImageSizeFromPath(imgPath);
    

    Check the link:
    https://forums.xamarin.com/discussion/32974/how-to-get-an-original-image-size

Sign In or Register to comment.