css裁剪图像然后按百分比缩放

时间:2012-04-19 22:13:42

标签: html css

我正在尝试裁剪(非背景)图像,然后按照正文的百分比缩放裁剪后的图像。我的想法是将我网站上的所有徽标和基本图形组合成一个图像,以便浏览器可以缓存图像(在第一次下载后更快)。然后我想相对于体宽进行缩放,这样无论用户的显示器尺寸如何,我的网站都会看起来与页面宽度的比例相同。

如果我给出html& css然后解释它:

<html>
<head>
    <style>
    body
    {
        padding: 0px;
        margin: 0px;
        width: 100%
    }
    #crop1
    {
        float: left;
        overflow: hidden;
        border: 1px solid red;
        clear: both;
    }
    #crop1 img
    {
        vertical-align: middle;
        margin: -28px 0px -88px -189px; /*top right bottom left*/
    }
    #scale1
    {
        width: 10%;
        border: 1px solid blue;
    }
    #scale1 img
    {
        vertical-align: middle;
        width: 100%;
    }
    #crop2
    {
        float: left;
        overflow: hidden;
        border: 1px solid green;
        width: 100%;
    }
    #crop2 img
    {
        vertical-align: middle;
        margin: -28px 0px -88px -189px; /*top right bottom left*/
    }
    #scale2
    {
        width: 10%;
        border: 1px solid orange;
        clear: both;
    }
    </style>
</head>
<body>
    <img src="http://www.mathleague.com/help/geometry/IMG00088.gif">
    <div id="scale1"><img src="http://www.mathleague.com/help/geometry/IMG00088.gif"></div>
    <div id="crop1"><img src="http://www.mathleague.com/help/geometry/IMG00088.gif"></div>
    <div id="scale2"><div id="crop2"><img src="http://www.mathleague.com/help/geometry/IMG00088.gif"></div></div>
</body>
</html>

我在这个例子中使用了图像http://www.mathleague.com/help/geometry/IMG00088.gif。我不打算在我的网站上使用这个图片,但原理是一样的。

首先,我只是将原始图像保持不变,在调试时给出一个大小参考:

<img src="http://www.mathleague.com/help/geometry/IMG00088.gif">

将单独的图像缩小到页面宽度的10%可以正常工作:

<div id="scale1">
    <img src="http://www.mathleague.com/help/geometry/IMG00088.gif">
</div>

向下裁剪图像以显示椭圆形状也可以正常工作:

<div id="crop1">
    <img src="http://www.mathleague.com/help/geometry/IMG00088.gif">
</div>

但我不能将椭圆缩小到页面宽度的10%:

<div id="scale2">
    <div id="crop2">
        <img src="http://www.mathleague.com/help/geometry/IMG00088.gif">
    </div>
</div>

(这会将椭圆形缩小到10%宽度,而不是缩放它)。也许我在最后一行遗漏了一些简单的css属性,或者我可能需要添加更多div s。我被卡住了。

以下是示例图片:
Example image

注意:解决方案必须兼容跨浏览器

4 个答案:

答案 0 :(得分:1)

目前图像不是继承父级的宽度,你可以通过声明'width:inherit;'来显式强制它。在图像上:

#crop2 img
{
    vertical-align: middle;
    margin: -28px 0px -88px -189px; /*top right bottom left*/
    width: inherit;
}

忘记提及,你需要重新调整边距以适应新尺寸的图像。

答案 1 :(得分:1)

更新了工作示例(边距需要为百分比)

要做到这一点你将要比你意识到的要复杂得多。对于最终的尺寸调整,您需要根据整体占据的百分比的倒数重新调整img大小。然后你必须采用它并将其与缩放相乘,然后乘以边距的偏移量。

编辑以下代码更精确,因为我能够检查并更正我的数学,并根据your easier image计算(知道大小和偏移是至关重要的)。 The new example更接近正确的大小计算。我在下面调整了以显示数学。来发现,计算比我想象的“更容易”,但我部分未能解释的是,即使偏移顶部和底部也应该从图像的原始宽度开始,因为宽度是整个图像的缩放。

#scale1
{
    width: 10%;
    padding: 0;
    margin: 0;
}

#crop1
{
    overflow: hidden;
    border: 1px solid green;
    width: 100%;
    padding: 0;
    margin: 0;
}

/*Image: 300 W x 209 H
  Offsets: oT = 8, oR = 56, oB = 75, oL = 204
  Icon: 40 w x 126 h */

#crop1 img
{
    width: 750% /* 1 / (40 / 300) [inverse of icon width / image width] */;
    vertical-align: middle;
    /*using the offsets, each has a percentage calculated based solely off 
      the image width, then adjusted based off the width % of the img as 
      calculated above */
    margin: -20%    /* (8 / 300) x 7.5 [the 750%] = 100 x 8 / 40*/
            0       /* right margin seems unnecessary, but if found otherwise, the
                 calculation would be (56 /300) x 7.5 = 100 x 56 / 40*/
            -187.5% /* (75 /300) x 7.5  = 100 x 75 / 40*/
            -510%;  /* (204 / 300)  x 7.5  = 100 x 204 / 40*/
    padding: 0;
    border: 0;
}

答案 2 :(得分:0)

改为使用background-positionbackground-size属性。

你的例子:

<!DOCTYPE html>

<style type="text/css">
.pentagon, .pentagon_large {
    background: url(IMG00088.GIF);
}
.pentagon {
    width: 110px;
    height: 110px;
    background-position: 0px 0px;
    background-repeat: no-repeat;
}
.pentagon_large {
    width: 220px;
    height: 220px;
    background-position: 0px 0px;
    background-repeat: no-repeat;
    background-size: 300%;
}
</style>

<body>

<div class="pentagon">&nbsp;</div>
<div class="pentagon_large">&nbsp;</div>

输出:

Output with this code

注意:使用IE9中的F12开发人员工具,您可以编辑值(见图片)以快速找到合适的尺寸。

答案 3 :(得分:0)

最后我采用了以下方法:

<!DOCTYPE html>
<html>
<head>
    <style>
    body
    {
        padding: 0px;
        margin: 0px;
        width: 100%
    }
    #d2
    {
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        position: absolute;
        overflow: hidden;
    }
    #d1
    {
        bottom: 0;
        right: 0;
        width: 251.59%; /*B*/
        height: 152.31%; /*C*/
        position: absolute;
    }
    #d0
    {
        top: 0;
        left: 0;
        width: 100%; /*A*/
        position: absolute;
    }
    #d0 img
    {
        width: 100%;
        float: left;
    }
    #container
    {
        top: 100px; /*final position of the copped section from the page top (in px)*/
        left: 40%; /*final left position of the copped section relative to page width*/
        display: inline-block;
        position: relative;
        width: 30%; /*final width of the copped selection relative to the page width*/
    }
    #dummy
    {
        margin-top: 51.587%; /*R*/
    }
    </style>
</head>
<body>
    <div id="container"><div id="dummy"></div>
        <div id="d2"><div id="d1"><div id="d0"><img src="http://i.stack.imgur.com/MLWNd.gif"></div></div></div>
    </div>
</body>
</html>

所需的输入是:selection_width,selection_height,selection_top,selection_left和image_width,如下所示:

image to be cropped and scaled

(image_width是此处显示的整个图像的宽度)。这样:

selection_top:    34 (just inside the boundary so that we do not show the border)
selection_left:   191 (also just inside the boundary so that we do not show the border)
selection_width:  126 (=317-191 where 317 is also just inside the right-side boundary)
selection_height: 65 (=99-34 where 99 is also just inside the bottom boundary)
image_width:      318

并且所需的输出是A,B,C,R(来自上面代码中的注释)。处理这些数字给出了:

A: 100.32%
B: 251.59%
C: 152.31%
R: 51.587%

现在浏览器窗口可以取消最大化并调整大小,椭圆将保持其原始形状,同时始终是页面宽度的百分比,并且从左侧开始以页面宽度的百分比定位。换句话说,浏览器在任何屏幕上看起来总是看起来相同。请注意,由于渲染不准确,椭圆周围的边框确实显得微弱,即使selection_ *指定最终图像将在显示的选区边框内。因此,最好在最终单张图像中的裁剪选择之间留下几个像素。

现在,您可以将整个网站的所有主题图像放在一个图像上,并使用此技术提取各种组件和位置,并根据需要进行缩放。这解决了有限并行下载的问题(存在于大多数浏览器中)。我已经完成了这个单个图像中所有形状的示例,在这里对齐以适应页面的宽度:http://jsfiddle.net/KsNku/(如果有人遇到不能像这样呈现此代码的浏览器:http://i.stack.imgur.com/O50vX.png请让我知道,我将编辑CSS以解决问题)。尝试调整jsfiddle浏览器窗口的大小,看看一切看起来如何保持静止,没有任何javascript !!

当然,完全由这种类型的布局组成的网站需要仔细设计 - 用户无法放大任何内容,除非他们可以进一步最大化屏幕。这意味着移动设备将显示页面非常小。如果这是一个问题,那么该技术可以用于有限的区域(例如,弹出窗口中的图像)。如果您知道所有用户都不会使用移动设备访问此网站(可能是因为您有一个针对移动电话用户的单独子域),那么此技术应该没问题。