(orig_w, orig_h, target_area, divisor=64)
| 60 | |
| 61 | |
| 62 | def calculate_new_size(orig_w, orig_h, target_area, divisor=64): |
| 63 | target_ratio = orig_w / orig_h |
| 64 | |
| 65 | def check_valid(w, h): |
| 66 | if w <= 0 or h <= 0: |
| 67 | return False |
| 68 | return w * h <= target_area and w % divisor == 0 and h % divisor == 0 |
| 69 | |
| 70 | def get_ratio_diff(w, h): |
| 71 | return abs(w / h - target_ratio) |
| 72 | |
| 73 | def round_to_64(value, round_up=False, divisor=64): |
| 74 | if round_up: |
| 75 | return divisor * ((value + (divisor - 1)) // divisor) |
| 76 | return divisor * (value // divisor) |
| 77 | |
| 78 | possible_sizes = [] |
| 79 | |
| 80 | max_area_h = int(np.sqrt(target_area / target_ratio)) |
| 81 | max_area_w = int(max_area_h * target_ratio) |
| 82 | |
| 83 | max_h = round_to_64(max_area_h, round_up=True, divisor=divisor) |
| 84 | max_w = round_to_64(max_area_w, round_up=True, divisor=divisor) |
| 85 | |
| 86 | for h in range(divisor, max_h + divisor, divisor): |
| 87 | ideal_w = h * target_ratio |
| 88 | |
| 89 | w_down = round_to_64(ideal_w) |
| 90 | w_up = round_to_64(ideal_w, round_up=True) |
| 91 | |
| 92 | for w in [w_down, w_up]: |
| 93 | if check_valid(w, h, divisor): |
| 94 | possible_sizes.append((w, h, get_ratio_diff(w, h))) |
| 95 | |
| 96 | if not possible_sizes: |
| 97 | raise ValueError("Can not find suitable size") |
| 98 | |
| 99 | possible_sizes.sort(key=lambda x: (-x[0] * x[1], x[2])) |
| 100 | |
| 101 | best_w, best_h, _ = possible_sizes[0] |
| 102 | return int(best_w), int(best_h) |
| 103 | |
| 104 | |
| 105 | def resize_by_area(image, target_area, keep_aspect_ratio=True, divisor=64, padding_color=(0, 0, 0)): |
no test coverage detected