2009-03-06 2 views
7

Например, если мне нужно, чтобы заполнить прямоугольник, который 100px в ширину 50px высотой, следующих входных изображений будет иметь следующее поведение:Масштаб изображения, чтобы полностью заполнить ограничивающего параллелепипеда

  1. 200w х 200h получает уменьшено на 50% и 25% отрубают сверху и дно.

  2. 200w x 100h уменьшается до 50% без обрезки.

  3. 100w x 200h получает не масштабируется, но 75px получают отрубленные сверху и снизу.

Похоже, что это была бы общая функция изменения размера, но я не смог отследить пример алгоритма.

Будет принимать ответ на любом языке, включая псевдокод. Хорошая ссылка на страницу с ответом!

+0

Кто-то оставил комментарий на мой ответ, я думал, что это ты, но это не так - можете ли вы немного рассказать о своих фактических ограничениях? Благодарю. –

+0

Общий случай - это то, что я хотел. Благодарю. – Larsenal

+0

Спасибо. Я отредактировал вводящую в заблуждение половину моего ответа. –

ответ

12

То, о чем вы просите, довольно легко. Вычислите различные коэффициенты масштабирования для ширины и высоты, затем выберите большую для вашего фактического масштабного коэффициента. Умножьте свой размер ввода на шкалу, и урожай, который выходит слишком большой.

scale = max(maxwidth/oldwidth, maxheight/oldheight) 
scaledwidth = oldwidth * scale 
scaledheight = oldheight * scale 
if scaledheight > maxheight: 
    croptop = (scaledheight - maxheight)/2 
    cropbottom = (scaledheight - maxheight) - croptop 
if scaledwidth > maxwidth: 
    cropleft = (scaledwidth - maxwidth)/2 
    cropright = (scaledwidth - maxwidth) - cropleft 
+0

Только X (ширина) находится под ограничениями изменения размера. Другой Y (высота) обрезается. – Suroot

+0

Это ограничение не было изложено и не было видно из ваших примеров. В этом случае используйте scale = maxwidth/oldwidth вместо этого и удалите вычисления cropleft/cropright, остальные останутся прежними. –

+0

Должны ли мы округлять выходные числа, поскольку они часто являются частями пикселя? –

1

Здесь мы проверяем, что мы только масштабируем, если X больше 100%; то после того, как мы это сделаем, мы гарантируем, что мы только 50 px на нашем Y. Если мы больше 50, тогда мы принимаем разницу и делим на 2, чтобы получить сумму, удаленную сверху/снизу.

double percent_x = 1.0; 

if(X > 100) { 
percent_x = (float)100/X; 
X *= percent_x; 
Y *= percent_x; 
} 

int diff_y; 
int top_cut, bott_cut; 
if(Y > 50) { 
diff_y = (Y - 50)/2; 
top_cut = bott_cut = diff_y; 
} 
0

Во многом вдохновлен ответ Марк Рэнсом в (спасибо так много - ты спас меня). Для тех, кто хотел бы сделать это без кадрирование изображения (только укладывающийся в пределах), я обнаружил, что это работает:

if (maxWidth > width && maxHeight > height) { 
    return { width, height }; 
} 

aspectRatio = width/height, 
scale  = max(maxWidth/width, maxHeight/height); 

scaledHeight = height * scale, 
scaledWidth = width * scale; 

if (scaledHeight > maxHeight) { 
    scaledHeight = maxHeight; 
    scaledWidth = aspectRatio * scaledHeight; 
} else if (scaledWidth > maxWidth) { 
    scaledWidth = maxWidth; 
    scaledHeight = scaledWidth/aspectRatio; 
} 

return { scaledHeight, scaledWidth }; 

 Смежные вопросы

  • Нет связанных вопросов^_^