Determining correct box to place image according to ratio

Hey all I am in need of some help with determines what box I need to place a given image into depending on that images ratio (image width / image height) to the box areas Aspect Ratio (box width / box height).

The code below is what I currently have that I am using to determine this (which does not work):

public static Dictionary<string, List<double>> sizeOfPhotoBoxes = new Dictionary<string, List<double>>()
{/*
                                               [Width]
                                              |     [Height]
                                              |     |      [Aspact Ratio]
                                             â†“    â†“    â†“
        KEY:         VALUE(s):   [1]  [2]  [3]*/
     { "box1", new List<double> {357, 272, 1.31} },
     { "box2", new List<double> {357, 272, 1.31 } },
     { "box3", new List<double> {365, 460, 0.79 } },
     { "box4", new List<double> {365, 265, 1.38 } },
     { "box5", new List<double> {715, 455, 1.57 } },
     { "box6", new List<double> {360, 465, 0.77 } },
     { "box7", new List<double> {360, 465, 0.77 } },
     { "box8", new List<double> {360, 465, 0.77 } },
     { "box9", new List<double> {540, 290, 1.86 } },
    { "box10", new List<double> {540, 290, 1.86 } }
};

double RA = (double)item.images[0].width / item.images[0].height;

foreach (var AR in sizeOfPhotoBoxes)
{
   if (AR.Value[2] >= RA && AR.Value[2] <= RA)
   {
      System.Diagnostics.Debug.WriteLine("found");
   }
}

I'm trying to figure out how to loop through my boxes' Aspect Ratio's to determine which box that image should go into according to that image Ratio. Currently with the code above, I am not getting the "found" output.

A few image samples:

1) 960/720 = 1.33

2) 1440/800 = 1.8

3) 1078/1440 = 0.74

4) 2048/1152 = 1.77

So taking the example above:

Image 1 would be best in Box 1 or 2 since that box has a 1.31 Aspect Ratio.

Image 2 would be best in box 9 or 10 since that box has a 1.86 Aspect Ratio.

Image 3 would be best in box 6, 7 or 8 since that box has a 0.77 Aspect Ratio.

Image 4 would be best in box 9 or 10 since that box has a 1.86 Aspect Ratio.

Any help with the code to determine this above would be great! Thanks!!
StealthrtAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

it_saigeDeveloperCommented:
You have to set variance limits since you are not dealing with explicit matches:
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_Q29087094
{
    class Program
    {
        static Dictionary<string, List<double>> photoBoxes = new Dictionary<string, List<double>>
        {
            { "box1", new List<double> {357, 272, 1.31} },
            { "box2", new List<double> {357, 272, 1.31 } },
            { "box3", new List<double> {365, 460, 0.79 } },
            { "box4", new List<double> {365, 265, 1.38 } },
            { "box5", new List<double> {715, 455, 1.57 } },
            { "box6", new List<double> {360, 465, 0.77 } },
            { "box7", new List<double> {360, 465, 0.77 } },
            { "box8", new List<double> {360, 465, 0.77 } },
            { "box9", new List<double> {540, 290, 1.86 } },
            { "box10", new List<double> {540, 290, 1.86 } }
        };

        static void Main(string[] args)
        {
            var photos = new[] { new[] { 960, 720 }, new[] { 1440, 800 }, new[] { 1078, 1440 }, new[] { 2048, 1152 } };
            foreach (var photo in photos)
            {
                var boxes = (from box in photoBoxes
                             let ratio = photo[0] / (double)photo[1]
                             /* box ratio matches photo ratio */
                             where ratio == box.Value[2] ||
                             /* if photo ratio less than box ratio and
                              * box ratio - photo ratio is less than or equal to .1 */
                             (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
                             /* if photo ratio greater than box ratio and
                              * photo ratio - box ratio is less than or equal to .1 */
                             (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
                             select box);
                foreach (var box in boxes)
                {
                    Console.WriteLine($"Found match for photo {string.Join("x", photo)} with aspect ratio {(photo[0] / (double)photo[1]):N2}; {box.Key} is {string.Join("x", box.Value.Take(2).ToArray())} with an aspect ratio of {box.Value.Last()}");
                }
            }

            Console.ReadLine();
        }
    }
}

Open in new window

Which produces the following output -Capture.PNG
-saige-
0
StealthrtAuthor Commented:
Thats great @saige but I am looking to do 1 image at a time.

I did a little modding of your code:

 
double RA = (double)item.images[0].width / item.images[0].height;
var photo = new[] { new[] { item.images[0].width, item.images[0].height } };

//foreach (var photo in photos)
// {
       var boxes = (from box in sizeOfPhotoBoxes
          let ratio = RA
          where ratio == box.Value[2] ||
                 (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
                 (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
          select box);

       foreach (var box in boxes)
       {
            Console.WriteLine($"Found match for photo with aspect ratio {box.Key} is {box.Value.Take(2).ToArray()} with an aspect ratio of {box.Value.Last()}");
       }
}

Open in new window

But it produces no returned values.
0
it_saigeDeveloperCommented:
If you simply want to pass in a photo to a method then you would do something like this:
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_Q29087094
{
    class Program
    {
        static Dictionary<string, List<double>> photoBoxes = new Dictionary<string, List<double>>
        {
            { "box1", new List<double> {357, 272, 1.31} },
            { "box2", new List<double> {357, 272, 1.31 } },
            { "box3", new List<double> {365, 460, 0.79 } },
            { "box4", new List<double> {365, 265, 1.38 } },
            { "box5", new List<double> {715, 455, 1.57 } },
            { "box6", new List<double> {360, 465, 0.77 } },
            { "box7", new List<double> {360, 465, 0.77 } },
            { "box8", new List<double> {360, 465, 0.77 } },
            { "box9", new List<double> {540, 290, 1.86 } },
            { "box10", new List<double> {540, 290, 1.86 } }
        };

        static void Main(string[] args)
        {
            var photos = new[] { new[] { 960, 720 }, new[] { 1440, 800 }, new[] { 1078, 1440 }, new[] { 2048, 1152 } };
            foreach (var photo in photos)
            {
                var boxes = GetBoxes(photo);
                foreach (var box in boxes)
                {
                    Console.WriteLine($"Found match for photo {string.Join("x", photo)} with aspect ratio {(photo[0] / (double)photo[1]):N2}; {box.Key} is {string.Join("x", box.Value.Take(2).ToArray())} with an aspect ratio of {box.Value.Last()}");
                }
            }

            Console.ReadLine();
        }

        static IEnumerable<KeyValuePair<string, List<double>>> GetBoxes(int[] photo)
        {
            return (from box in photoBoxes
                    let ratio = photo[0] / (double)photo[1]
                    where ratio == box.Value[2] ||
                    (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
                    (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
                    select box);
        }
    }
}

Open in new window

Which gives the same output as above.  But in reviewing your code you seem to be getting your width and height from an image list of a sorts.  So perhaps you are looking for something more along the lines of:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

namespace EE_Q29087094
{
    class Program
    {
        static Dictionary<string, List<double>> photoBoxes = new Dictionary<string, List<double>>
        {
            { "box1", new List<double> {357, 272, 1.31} },
            { "box2", new List<double> {357, 272, 1.31 } },
            { "box3", new List<double> {365, 460, 0.79 } },
            { "box4", new List<double> {365, 265, 1.38 } },
            { "box5", new List<double> {715, 455, 1.57 } },
            { "box6", new List<double> {360, 465, 0.77 } },
            { "box7", new List<double> {360, 465, 0.77 } },
            { "box8", new List<double> {360, 465, 0.77 } },
            { "box9", new List<double> {540, 290, 1.86 } },
            { "box10", new List<double> {540, 290, 1.86 } }
        };

        static void Main(string[] args)
        {
            var photos = new[] { new Bitmap(960, 720), new Bitmap(1440, 800), new Bitmap(1078, 1440), new Bitmap(2048, 1152) };
            foreach (var photo in photos)
            {
                var boxes = GetBoxes(new[] { photo.Width, photo.Height });
                foreach (var box in boxes)
                {
                    Console.WriteLine($"Found match for photo {string.Join("x", new[] { photo.Width, photo.Height })} with aspect ratio {(photo.Width / (double)photo.Height):N2}; {box.Key} is {string.Join("x", box.Value.Take(2).ToArray())} with an aspect ratio of {box.Value.Last()}");
                }
            }

            Console.ReadLine();
        }

        static IEnumerable<KeyValuePair<string, List<double>>> GetBoxes(int[] photo)
        {
            return (from box in photoBoxes
                    let ratio = photo[0] / (double)photo[1]
                    where ratio == box.Value[2] ||
                    (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
                    (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
                    select box);
        }
    }
}

Open in new window

Or better yet
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

namespace EE_Q29087094
{
    class Program
    {
        static Dictionary<string, List<double>> photoBoxes = new Dictionary<string, List<double>>
        {
            { "box1", new List<double> {357, 272, 1.31} },
            { "box2", new List<double> {357, 272, 1.31 } },
            { "box3", new List<double> {365, 460, 0.79 } },
            { "box4", new List<double> {365, 265, 1.38 } },
            { "box5", new List<double> {715, 455, 1.57 } },
            { "box6", new List<double> {360, 465, 0.77 } },
            { "box7", new List<double> {360, 465, 0.77 } },
            { "box8", new List<double> {360, 465, 0.77 } },
            { "box9", new List<double> {540, 290, 1.86 } },
            { "box10", new List<double> {540, 290, 1.86 } }
        };

        static void Main(string[] args)
        {
            var photos = new[] { new Bitmap(960, 720), new Bitmap(1440, 800), new Bitmap(1078, 1440), new Bitmap(2048, 1152) };
            foreach (var photo in photos)
            {
                var boxes = GetBoxes(photo);
                foreach (var box in boxes)
                {
                    Console.WriteLine($"Found match for photo {string.Join("x", new[] { photo.Width, photo.Height })} with aspect ratio {(photo.Width / (double)photo.Height):N2}; {box.Key} is {string.Join("x", box.Value.Take(2).ToArray())} with an aspect ratio of {box.Value.Last()}");
                }
            }

            Console.ReadLine();
        }

        static IEnumerable<KeyValuePair<string, List<double>>> GetBoxes(Image photo)
        {
            return (from box in photoBoxes
                    let ratio = photo.Width / (double)photo.Height
                    where ratio == box.Value[2] ||
                    (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
                    (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
                    select box);
        }
    }
}

Open in new window

Which all produce the same output as above.

-saige-
0
Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

StealthrtAuthor Commented:
I would only be using 1 image at a time. The images I get are already in a for loop so I just deal with 1 image at a time.

Your examples seem to still have "photos" where all I would need is just 1 photo.
0
it_saigeDeveloperCommented:
Main is looping through the photos in the array/list of photos, for each one of those photos it feeds the photo to the GetBoxes method, you simply have to choose which signature you want to use; e.g. -
double ratio = (double)item.images[0].width / item.images[0].height;

var boxes = GetBoxes(ratio);

Open in new window

The GetBoxes method would then look like this:
static IEnumerable<KeyValuePair<string, List<double>>> GetBoxes(double ratio)
{
    return (from box in photoBoxes
            where ratio == box.Value[2] ||
            (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
            (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
            select box);
}

Open in new window

Boxes is an enumerable of boxes where the ratio meets the requirements, to access each one you have to loop:
foreach (var box in boxes)
{
    // You got one of your matches, now do something with it
    Console.WriteLine($"Box: {box.Key}; Values: {{ {string.Join(", ", box.Value.ToArray())} }}");
}

Open in new window


-saige-
0
StealthrtAuthor Commented:
Not sure what i am doing wrong but i seem to keep getting nothing..
loopErr1.png
0
StealthrtAuthor Commented:
Hum.. i think i found out what is wrong. I am using 528, 960 and that seems to come back with nothing...
0
it_saigeDeveloperCommented:
You are correct, the aspect ratio of .55 is outside the bounds set by the variance limits.  To ensure that we return results when the photo's are outside the range of the variances, we need to include one more check and get the lowest or greatest ratio'd boxes; e.g. -
static IEnumerable<KeyValuePair<string, List<double>>> GetBoxes(double ratio)
{
    var ratios = (from box in photoBoxes orderby box.Value[2] select box.Value[2]);
    if (ratio < ratios.First())
    {
        return (from box in photoBoxes
                where box.Value[2] == ratios.First()
                select box);
    }
    else if (ratio > ratios.Last())
    {
        return (from box in photoBoxes
                where box.Value[2] == ratios.Last()
                select box);
    }
    return (from box in photoBoxes
            where ratio == box.Value[2] ||
            (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
            (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
            select box);
}

Open in new window

Proof of concept -
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

namespace EE_Q29087094
{
    class Program
    {
        static Dictionary<string, List<double>> photoBoxes = new Dictionary<string, List<double>>
        {
            { "box1", new List<double> {357, 272, 1.31} },
            { "box2", new List<double> {357, 272, 1.31 } },
            { "box3", new List<double> {365, 460, 0.79 } },
            { "box4", new List<double> {365, 265, 1.38 } },
            { "box5", new List<double> {715, 455, 1.57 } },
            { "box6", new List<double> {360, 465, 0.77 } },
            { "box7", new List<double> {360, 465, 0.77 } },
            { "box8", new List<double> {360, 465, 0.77 } },
            { "box9", new List<double> {540, 290, 1.86 } },
            { "box10", new List<double> {540, 290, 1.86 } }
        };

        static void Main(string[] args)
        {
            var photos = new[] { new Bitmap(960, 720), new Bitmap(1440, 800), new Bitmap(1078, 1440), new Bitmap(2048, 1152), new Bitmap(528, 960) };
            foreach (var photo in photos)
            {
                var boxes = GetBoxes(photo.Width / (double)photo.Height);
                foreach (var box in boxes)
                {
                    Console.WriteLine($"Found match for photo {string.Join("x", new[] { photo.Width, photo.Height })} with aspect ratio {(photo.Width / (double)photo.Height):N2}; {box.Key} is {string.Join("x", box.Value.Take(2).ToArray())} with an aspect ratio of {box.Value.Last()}");
                }
            }

            Console.ReadLine();
        }

        static IEnumerable<KeyValuePair<string, List<double>>> GetBoxes(double ratio)
        {
            var ratios = (from box in photoBoxes orderby box.Value[2] select box.Value[2]);
            if (ratio < ratios.First())
            {
                return (from box in photoBoxes
                        where box.Value[2] == ratios.First()
                        select box);
            }
            else if (ratio > ratios.Last())
            {
                return (from box in photoBoxes
                        where box.Value[2] == ratios.Last()
                        select box);
            }
            return (from box in photoBoxes
                    where ratio == box.Value[2] ||
                    (ratio < box.Value[2] && box.Value[2] - ratio <= .1) ||
                    (ratio > box.Value[2] && ratio - box.Value[2] <= .1)
                    select box);
        }
    }
}

Open in new window

Now produces the following output -Capture.PNG
-saige-
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
StealthrtAuthor Commented:
Awesome! Thanks saige!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.