2010-06-09 99 views
9

我有一个应用程序,最终用户可以在设计器中调整大小和定位图像。由于规范要求图像被“拉伸”到包含控件,最终用户最终可能会得到一张尴尬拉伸的图像。如何将显示图像“智能调整大小”为原始高宽比

为了帮助图像的用户上浆我想实现一个智能大小调整功能,这将使用户可以轻松地修复图像的纵横比例,使之不再出现捉襟见肘的。

快速的方法来解决,这是实际提供两种选择:1)从高宽2)规模的规模。用户选择该方法,算法通过使用原始宽高比来调整图片的大小。例如:图片在设计器上显示为200x200,但原始图像为1024x768像素。用户选择“智能尺寸从宽度”,新的尺寸变成〜200x150,因为原始纵横比是〜1.333

没关系,但我怎么能让算法更聪明,而且不会打扰用户通过询问重新计算哪个维度应该基于?

回答

22

如果我正确地解释你的天赋,你想要一个结果,该结果并不比一个终端用户奠定较大原来;你希望两个维度中的一个缩小,另一个保持不变。换句话说,新尺寸应该在一个方向上填充设计师空间,同时缩短另一个方向的尺寸以保持原始高宽比。

original_ratio = original_width/original_height 
designer_ratio = designer_width/designer_height 
if original_ratio > designer_ratio 
    designer_height = designer_width/original_ratio 
else 
    designer_width = designer_height * original_ratio 

通常你会使用整数坐标,但产生上述比率的分区需要浮点数。这个公式的重新排列是更整数友好的。确保您的整数具有处理最大宽度*高度的范围。

if original_width * designer_height > designer_width * original_height 
    designer_height = (designer_width * original_height)/original_width 
else 
    designer_width = (designer_height * original_width)/original_height 
+0

是的,规范需要扩展以定义实际进行的智能调整大小。这个算法听起来合理。我会试试看。 – 2010-06-09 19:15:16

1

计算的这两种方式的新尺寸(“刻度由宽度”和“由规模高度”),然后使用适合于显示的一个。

另外,您也可以计算出“边框”的长宽比并将其与原始图像的宽高比。根据哪一个纵横比较大,高度或宽度需要缩放。

你,这样在任何情况下“由宽尺度”做也可能限制大小调整过程。然后,为了改变图像的大小,用户总是必须改变其宽度。高度将始终自动调整。

+0

我沿着这些线路的思考,但不要yhou如何确定什么是太宽或当太高,用户可任意大小和放置图像的JavaScript增长规模? – 2010-06-09 18:45:10

+0

@Paul:是不是限于200x200?目前的智能尺寸功能从哪里获得极限? – sth 2010-06-09 18:50:25

+0

我们正在接近。这些限制是用户通过操纵图像大小隐式设置的。看到我的回复下面的khnle。 – 2010-06-09 18:53:09

1

因为要最大限度地展示在你的窗口,尽可能缩放后的图像(正本),即在设计领域,你会采取的宽度或原始图像的高度大,规模,为200伪代码(宽度,高度是原始尺寸):

if (width > height) { 
    scaledWidth = 200; 
    scaledHeight = (height * 200)/width; 
} else { 
    scaledHeight = 200; 
    scaledWidth = (width * 200)/height; 
} 
+0

不,我希望图像的尺寸尽可能接近用户布置的尺寸。最后,其中一个维度将保持不变。 – 2010-06-09 18:50:40

0

你只需要计算出所需要的两个维度的规模,然后采取的2

2

较小的有没有占拷贝量和pasters那里诶!我也想知道这一点,我看到的所有缩放宽度或高度都是无穷无尽的例子。谁会希望其他的溢出?!对于宽度,所以无论图像

  • 调整大小的宽度和高度,而不需要为一个循环
  • 不超过图像原始尺寸
  • 用途可以正常工作,即宽度/方面的高度的数学和高度*方面实际上按比例适当上下:/

//////////////

private void ResizeImage(Image img, double maxWidth, double maxHeight) 
{ 
    double srcWidth = img.Source.Width; 
    double srcHeight = img.Source.Height; 

    double resizeWidth = srcWidth; 
    double resizeHeight = srcHeight; 

    double aspect = resizeWidth/resizeHeight; 

    if (resizeWidth > maxWidth) 
    { 
     resizeWidth = maxWidth; 
     resizeHeight = resizeWidth/aspect; 
    } 
    if (resizeHeight > maxHeight) 
    { 
     aspect = resizeWidth/resizeHeight; 
     resizeHeight = maxHeight; 
     resizeWidth = resizeHeight * aspect; 
    } 

    img.Width = resizeWidth; 
    img.Height = resizeHeight; 
} 
+0

相当不错,除了当你做ResizeImage(i,2000,3000) – 2013-03-18 14:19:43

6

这里的当我不得不处理这个问题时,我提出了一个解决方案。原来很简单直接的imo,只是想分享它。

手持 “公式”:ratio = W/HW = H * ratio

  1. 计算的比率。
  2. 如果您将宽度设置为新尺寸宽度(最大允许宽度),则计算图像的高度。
  3. 如果要将高度设置为新的尺寸高度(最大允许高度),请计算图像的宽度。
  4. 查看两种尺寸中的哪一种不会覆盖任何尺寸的最大尺寸。如果比例不是1,其中一个总是错误的,一个总是正确的。

在Javascript中

// Returns array with new width and height 
function proportionalScale(originalSize, newSize) 
{ 
    var ratio = originalSize[0]/originalSize[1]; 

    var maximizedToWidth = [newSize[0], newSize[0]/ratio]; 
    var maximizedToHeight = [newSize[1] * ratio, newSize[1]]; 

    if (maximizedToWidth[1] > newSize[1]) { return maximizedToHeight; } 
    else { return maximizedToWidth; } 
} 

originalSizenewSize是一个数组[0] = width[1] = height

2

注意到上面的建议,并使其向上扩展最大高度/宽度之内/向下。这里它的Python代码,并且还增加了对旋转的东西而限制一个内保持:

DEF _resize(图像,尺寸,旋转=无): “”” 调整大小的图像被尽可能接近到指定的尺寸图像是一个 django图像模型字段。

Will both scale up and down the image to meet this while keeping the proportions 
    in width and height 

""" 

if image and os.path.isfile(image.path): 

    im = pil.open(image.path) 
    logging.debug('resizing image from %s x %s --> %s x %s ' % (im.size[0], im.size[1], dimensions[0], dimensions[1])) 

    if rotate: 
     logging.debug('first rotating image %s' % rotate) 
     im = im.rotate(90) 

    srcWidth = Decimal(im.size[0]) 
    srcHeight = Decimal(im.size[1]) 

    resizeWidth = srcWidth 
    resizeHeight = srcHeight 

    aspect = resizeWidth/resizeHeight # Decimal 

    logging.debug('resize aspect is %s' % aspect) 

    if resizeWidth > dimensions[0] or resizeHeight > dimensions[1]: 
     # if width or height is bigger we need to shrink things 
     if resizeWidth > dimensions[0]: 
      resizeWidth = Decimal(dimensions[0]) 
      resizeHeight = resizeWidth/aspect 

     if resizeHeight > dimensions[1] : 
      aspect = resizeWidth/resizeHeight 
      resizeHeight = Decimal(dimensions[1]) 
      resizeWidth = resizeHeight * aspect 

    else: 
     # if both width and height are smaller we need to increase size 
     if resizeWidth < dimensions[0]: 
      resizeWidth = Decimal(dimensions[0]) 
      resizeHeight = resizeWidth/aspect 

     if resizeHeight > dimensions[1] : 
      aspect = resizeWidth/resizeHeight 
      resizeHeight = Decimal(dimensions[1]) 
      resizeWidth = resizeHeight * aspect 

    im = im.resize((resizeWidth, resizeHeight), pil.ANTIALIAS) 

    logging.debug('resized image to %s %s' % im.size) 
    im.save(image.path) 

else: 
    # no action, due to no image or no image in path 
    pass 

return image 
0

这里是我的解决方案,

一个=方面 SW =原始图像宽度 SH =原始图像高度 DW =请求的最大宽度 DH =请求的最大高度

SW和sh将包含最终调整大小的值

代码是PHP:

$a = $sw/$sh; 

if($a > 1){ 
    // wider image 
    if($sw != $dw){ 
     $rt = $dw/$sw; 
     $sw = $sw * $rt; 
     $sh = $sh * $rt; 
    } 

    if($sh > $dh){ 
     $rt = $dh/$sh; 
     $sw = $sw * $rt; 
     $sh = $sh * $rt; 
    } 
}else{ 
    // taller image 
    if($sh != $dh){ 
     $rt = $dh/$sh; 
     $sh = $sh * $rt; 
     $sw = $sw * $rt; 
    } 

    if($sw > $dw){ 
     $rt = $dw/$sw; 
     $sh = $sh * $rt; 
     $sw = $sw * $rt; 
    } 
} 
0

我用这样的方式将图像尺寸调整到FHD方式

if (width >= height) { 
    var original_ratio = width/height 
    new_width = 1080 * original_ratio 
    console.log("new new_width = " + Math.round(new_width)); 
    console.log("new new_height = 1080"); 
} else { 
    var original_ratio = height/width 
    new_height = 1080 * original_ratio 
    console.log("new new_height = " + Math.round(new_height)); 
    console.log("new new_width = 1080"); 
} 

您可以将1080更改为新的大小。

我希望这对至少有人有用。

0

我的解决方案,以缩小和基于https://stackoverflow.com/a/5654847/1055015

var scale = function (srcWidth, srcHeight, maxWidth, maxHeight) { 

     let resizeWidth = srcWidth; 
     let resizeHeight = srcHeight; 

     let aspect = resizeWidth/resizeHeight; 
     let scaleX = maxWidth/srcWidth; 
     let scaleY = maxHeight/srcHeight; 
     let scale = Math.min(scaleX, scaleY); 

     resizeWidth *= scale; 
     resizeHeight *= scale; 

     if (resizeWidth > maxWidth) { 
     resizeWidth = maxWidth; 
     resizeHeight = resizeWidth/aspect; 
     } 

     if (resizeHeight > maxHeight) { 
     aspect  = resizeWidth/resizeHeight; 
     resizeHeight = maxHeight; 
     resizeWidth = resizeHeight * aspect; 
     } 

     return { 
     width : resizeWidth, 
     height: resizeHeight, 
     }; 
    } 
相关问题