title: How to resize an image in python, while retaining aspect ratio, given a target size?
body: <p>First off part of me feels like this is a stupid question, sorry about that. Currently the most accurate way I've found of calculating the optimum scaling factor (best width and height for target pixel count while retaining aspect ratio) is iterating through and choosing the best one however there must be a better way of doing this.</p>
  
  <p>An example:</p>
  
  <pre><code>import cv2, numpy as np
  img = cv2.imread("arnold.jpg")
  
  img.shape[1] # e.g. width  = 700
  img.shape[0] # e.g. height = 979
  
  # e.g. Total  pixels : 685,300
  
  TARGET_PIXELS = 100000
  MAX_FACTOR    = 0.9
  STEP_FACTOR   = 0.001
  iter_factor   = STEP_FACTOR
  results       = dict()
  
  while iter_factor &lt; MAX_RATIO:
       img2 = cv2.resize(img, (0,0), fx=iter_factor, fy=iter_factor)
       results[img2.shape[0]*img2.shape[1]] = iter_factor
       iter_factor += step_factor
  
  best_pixels = min(results, key=lambda x:abs(x-TARGET_PIXELS))
  best_ratio  = results[best_pixels]
  
  print best_pixels # e.g. 99750
  print best_ratio  # e.g. 0.208
  </code></pre>
  
  <p>I know there are probably some errors lying around in the code above i.e. there is no check in the results dictionary for an existing key but I am more concerned with a different approach which I cannot figure out was looking into lagrangian optimisation but that seems quite complex also for a simple problem. Any ideas?</p>
  
  <p>** EDIT AFTER ANSWER **</p>
  
  <p>Going to provide the code if anyone is interested in the answer</p>
  
  <pre><code>import math, cv2, numpy as np
  
  # load up an image
  img = cv2.imread("arnold.jpg")
  
  TARGET_PIXEL_AREA = 100000.0
  
  ratio = float(img.shape[1]) / float(img.shape[0])
  new_h = int(math.sqrt(TARGET_PIXEL_AREA / ratio) + 0.5)
  new_w = int((new_h * ratio) + 0.5)
  
  img2 = cv2.resize(img, (new_w,new_h))
  </code></pre>