Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

162
Views
Getting the most rectangular width and height values ​that can fit a large amount of pixels in an image

What's the best way to calculate the size needed to fit an array of pixels into an image as close as possible to a rectangle/square shape without losing or adding unnecessary pixels?

Using an image of 100 pixels as an example, the best size to fit all pixels would be 10x10, because 10*10 is 100, that is, it adds the least amount of extra pixels (in this case 0). 100x1 also fits all pixels, but it sure is much less rectangular than 10x10.

And in order to fit 101 pixels the best size is 8x13, although 8*13 is 104, it's the only multiplication that doesn't lose any pixels, adds few extra pixels (3), and has the most rectangular shape.

So far I have been able to solve this problem with the following rules:

  • Dividing width by height must result in a value greater than 0.5 and less than 1.5. (This will ensure that only the most rectangular values ​​are kept).
  • Multiplying width by height must result in a value greater than or equal to the number of pixels.

By applying these rules I end up with a variety of possibilities, the best one being the one that, when multiplied, most closely approximates the number of pixels.

Here's what my code looks like currently:

function loopPixels(pixels, callback) {
    for (let x = 2; x < pixels; x++) {
        for (let y = 2; y < pixels; y++) {
            callback(x, y);
        }
    }
}

function getRectangle(pixels) {
    let result = {extraPixels: pixels};
    loopPixels(pixels, (left, right) => {
        let half = (left/right);
        let total = (left*right);

        if (Math.round(half) == 1 && total >= pixels) {
            if (total-pixels < result.extraPixels) {
                result = {size: [left, right], extraPixels: total-pixels}; 
            }
        }
    })
    return result;
}

getRectangle(101) // must return [[8, 13], 3] (width, height and additional pixels)

What it does is keep a variable holding the smallest result of (width*height)-pixels, which is the difference between the found values ​​and the number of pixels.

Although it works fine for small amounts of pixels, with huge values (which would likely return 1000x1000 sizes), it's ultra slow.

Is there a specific reason for such slowness? and would it be possible to get the same result without using nested for loops?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

The following code can be made more efficient but it is very descriptive. It takes a pixel count (n) and a k value which denotes the best k matches.

Lets try 68M pixels for some resonable aspect ratios.

function getReasonableDimensions(n,k){
  var max = ~~Math.sqrt(n);
  return Array.from({length: max}, (_,i,a) => [n%(max-i),max-i])
              .sort((a,b) => a[0] - b[0])
              .slice(0,k)
              .map(t => [Math.floor(n/t[1]), t[1]]);
}

var res = getReasonableDimensions(68000000,10)
console.log(JSON.stringify(res));

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!