масштабировать изображение, сохраняя пропорции, не опускаясь ниже целей - PullRequest
5 голосов
/ 12 августа 2011

Интересно, кто-нибудь может мне помочь с математическим / псевдокодом / java кодом для масштабирования изображения до целевого измерения. Требуется сохранить соотношение сторон, но не опускаться ниже целевого размера как по шкалам x, так и по оси y. окончательный расчетный размер может быть больше, чем запрошенная цель, но он должен быть ближайшим к цели.

Пример: У меня есть изображение, которое 200x100. он должен быть уменьшен до целевого размера 30x10. Мне нужно найти минимальное измерение, которое сохраняет соотношение сторон источника, где как x, так и y масштабов, по крайней мере, то, что указано в цели. в нашем примере 20х10 не очень хорошо, потому что шкала х упала ниже цели (которая равна 30). ближайший из них будет 30х15

Спасибо.

Ответы [ 2 ]

10 голосов
/ 12 августа 2011
targetRatio = targetWidth / targetHeight;
sourceRatio = sourceWidth / sourceHeight;
if(sourceRatio >= targetRatio){ // source is wider than target in proportion
    requiredWidth = targetWidth;
    requiredHeight = requiredWidth / sourceRatio;      
}else{ // source is higher than target in proportion
    requiredHeight = targetHeight;
    requiredWidth = requiredHeight * sourceRatio;      
} 

Таким образом, ваше окончательное изображение:

  • всегда вписывается в цель, но не обрезается.

  • сохраняет исходное соотношение сторон.

  • и всегда имеет ширину или высоту (или оба), точно совпадающие с целью.

0 голосов
/ 12 августа 2011

Что ж, в вашем примере вы уже использовали алгоритм, который ищете.Я буду использовать пример, который вы дали.

Original          Target
200 x 100   ->    30 x 10

1. You take the bigger value of the target dimensions (in our case 30)
2. Check if its smaller than the corresponding original width or height
  2.1 If its smaller define this as the new width (So 30 is the new width)
  2.2 If its not smaller check the other part
3. Now we have to calculate the height which is simply the (30/200)*100

So as result you get like you wrote: 30 x 15

Надеюсь, это было понятно:)

В части кода вы можете использовать BufferedImage и просто создатьBufferedImage с правильным значением масштаба, как это.

BufferedImage before = getBufferedImage(encoded);
int w = before.getWidth();
int h = before.getHeight();
BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(2.0, 2.0); // <-- Here you should use the calculated scale factors
AffineTransformOp scaleOp = 
new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(before, after);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...