in src/base/image_processors_utils.js [816:907]
get_resize_output_image_size(image, size) {
// `size` comes in many forms, so we need to handle them all here:
// 1. `size` is an integer, in which case we resize the image to be a square
const [srcWidth, srcHeight] = image.size;
let shortest_edge;
let longest_edge;
if (this.do_thumbnail) {
// NOTE: custom logic for `Donut` models
const { height, width } = size;
shortest_edge = Math.min(height, width)
}
// Support both formats for backwards compatibility
else if (Number.isInteger(size)) {
shortest_edge = size;
// @ts-expect-error TS2339
longest_edge = this.config.max_size ?? shortest_edge;
} else if (size !== undefined) {
// Extract known properties from `size`
shortest_edge = size.shortest_edge;
longest_edge = size.longest_edge;
}
// If `longest_edge` and `shortest_edge` are set, maintain aspect ratio and resize to `shortest_edge`
// while keeping the largest dimension <= `longest_edge`
if (shortest_edge !== undefined || longest_edge !== undefined) {
// http://opensourcehacker.com/2011/12/01/calculate-aspect-ratio-conserving-resize-for-images-in-javascript/
// Try resize so that shortest edge is `shortest_edge` (target)
const shortResizeFactor = shortest_edge === undefined
? 1 // If `shortest_edge` is not set, don't upscale
: Math.max(shortest_edge / srcWidth, shortest_edge / srcHeight);
const newWidth = srcWidth * shortResizeFactor;
const newHeight = srcHeight * shortResizeFactor;
// The new width and height might be greater than `longest_edge`, so
// we downscale again to ensure the largest dimension is `longest_edge`
const longResizeFactor = longest_edge === undefined
? 1 // If `longest_edge` is not set, don't downscale
: Math.min(longest_edge / newWidth, longest_edge / newHeight);
// To avoid certain floating point precision issues, we round to 2 decimal places
let finalWidth = Math.floor(Number((newWidth * longResizeFactor).toFixed(2)));
let finalHeight = Math.floor(Number((newHeight * longResizeFactor).toFixed(2)));
if (this.size_divisibility !== undefined) {
[finalWidth, finalHeight] = enforce_size_divisibility([finalWidth, finalHeight], this.size_divisibility)
}
return [finalWidth, finalHeight];
} else if (size !== undefined && size.width !== undefined && size.height !== undefined) {
// If `width` and `height` are set, resize to those dimensions
let newWidth = size.width;
let newHeight = size.height;
// Custom for DPT models
if (this.config.keep_aspect_ratio && this.config.ensure_multiple_of) {
// determine new height and width
let scale_height = newHeight / srcHeight;
let scale_width = newWidth / srcWidth;
// scale as little as possible
if (Math.abs(1 - scale_width) < Math.abs(1 - scale_height)) {
// fit width
scale_height = scale_width;
} else {
// fit height
scale_width = scale_height;
}
newHeight = constraint_to_multiple_of(scale_height * srcHeight, this.config.ensure_multiple_of);
newWidth = constraint_to_multiple_of(scale_width * srcWidth, this.config.ensure_multiple_of);
}
return [newWidth, newHeight];
} else if (this.size_divisibility !== undefined) {
return enforce_size_divisibility([srcWidth, srcHeight], this.size_divisibility);
} else if (this.min_pixels !== undefined && this.max_pixels !== undefined) {
// Custom resize logic for Qwen2-VL models
// @ts-expect-error TS2339
const factor = this.config.patch_size * this.config.merge_size;
return smart_resize(srcHeight, srcWidth, factor, this.min_pixels, this.max_pixels);
} else {
throw new Error(`Could not resize image due to unsupported \`this.size\` option in config: ${JSON.stringify(size)}`);
}
}