2010-11-12 20 views
0

我在这里遇到了一些问题。我一直在试图用JavaScript做一个图片库,但是我遇到了一些问题。当第一张图片加载时,我可以调整图片的大小,但只要加载另一张图片,就不会调整大小!由于用户将能够上传很多不同大小的图片,我真的需要让它工作。将动态图像调整为不能运行一次以上

我检查了准备使用的图片库等,没有什么是做我需要做的。

这里是我的javascript:

function changeCurrentImage(conteneur) 
{ 
    var img = conteneur.getElementsByTagName("img"); 

    var imgUrl = img[0].src; 

    var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9); 
    var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.')); 
    var currentImg = document.getElementById('currentImage'); 
    currentImg.src = imgFirstPart + "borne" + imgLastPart; 

    resize(document.getElementById('currentImage'), 375, 655); 
} 

function resize(img, maxh, maxw) { 
    var ratio = maxh/maxw; 
    if (img.height/img.width > ratio){ 
    // height is the problem 
    if (img.height > maxh){ 
     img.width = Math.round(img.width*(maxh/img.height)); 
     img.height = maxh; 
    } 
    } else { 
    // width is the problem 
    if (img.width > maxw){ 
     img.height = Math.round(img.height*(maxw/img.width)); 
     img.width = maxw; 
    } 
    } 
}; 

这里是HTML(使用ASP.Net中继器):

<asp:Repeater ID="rptImages" runat="server"> 
<HeaderTemplate> 
</HeaderTemplate> 
<ItemTemplate> 
<a href="#"> 
    <div id="thumbnailImageContainer1" onclick="changeCurrentImage(this)"> 
     <div id="thumbnailImageContainer2"> 
      <img id="thumbnailImage" src="<%# SiteUrl + Eval("ImageThumbnailPath")%>?rn=<%=Random()%>" alt="Photo" onload="resize(this, 60, 105)" /> 
     </div> 
    </div> 
</a> 
</ItemTemplate> 
<FooterTemplate> 
</FooterTemplate> 
</asp:Repeater> 
+1

难道你不能在服务器端做到这一点?这将是更好的方式,因为用户可能被迫下载一个稍后调整大小的大文件。 – 2010-11-12 22:18:37

+1

在你的代码中,你在哪里设置“currentImage”作为id?也许我只是想念它,但它并没有出现在你的changeCurrentImage(没有setAttribute('id','currentImage')),并且你的ASP也不存在。然而,这是实际“调整大小”的图像。 – 2010-11-12 22:24:22

+0

@Jason:很好,但永远不会使用'setAttribute'来设置像'id'和'class'这样的属性。 IE会对此窒息。只需使用本地DOM属性,如'element.id'。 – 2010-11-12 22:41:23

回答

1

最有可能的图像还没有下载这么img.height和img.width还没有。从技术上讲,你不需要等到下载完整的图像,你可以用定时器轮询图像,直到宽度和高度不为零。这听起来很混乱,但如果你花时间做正确的话,可以做得很好。 (我有一个ImageLoader实用程序,我为此目的....只有一个计时器,即使它一次处理多个图像,并在具有尺寸时调用回调函数)我不得不不同意Marcel ....客户端很适合这种情况,即使图像来自服务器以外的其他来源,也可以工作。

编辑:添加ImageLoader的工具:

var ImageLoader = { 
    maxChecks: 1000, 
    list: [], 
    intervalHandle : null, 

    loadImage : function (callback, url, userdata) { 
    var img = new Image(); 
    img.src = url; 
    if (img.width && img.height) { 
     callback (img.width, img.height, url, 0, userdata); 
     } 
    else { 
     var obj = {image: img, url: url, callback: callback, 
       checks: 1, userdata: userdata}; 
     var i; 
     for (i=0; i < this.list.length; i++) { 
     if (this.list[i] == null) 
      break; 
     } 
     this.list[i] = obj; 
     if (!this.intervalHandle) 
     this.intervalHandle = setInterval(this.interval, 30); 
     } 
    }, 

    // called by setInterval 
    interval : function() { 
    var count = 0; 
    var list = ImageLoader.list, item; 
    for (var i=0; i<list.length; i++) { 
     item = list[i]; 
     if (item != null) { 
     if (item.image.width && item.image.height) { 
      item.callback (item.image.width, item.image.height, 
      item.url, item.checks, item.userdata); 
      ImageLoader.list[i] = null; 
      } 
     else if (item.checks > ImageLoader.maxChecks) { 
      item.callback (0, 0, item.url, item.checks, item.userdata); 
      ImageLoader.list[i] = null; 
      } 
     else { 
      count++; 
      item.checks++; 
      } 
     } 
     } 
    if (count == 0) { 
     ImageLoader.list = []; 
     clearInterval (ImageLoader.intervalHandle); 
     delete ImageLoader.intervalHandle; 
     } 
    } 
}; 

用法示例:

var callback = function (width, height, url, checks, userdata) { 
    // show stuff in the title 
    document.title = "w: " + width + ", h:" + height + 
     ", url:" + url + ", checks:" + checks + ", userdata: " + userdata; 
    var img = document.createElement("IMG"); 
    img.src = url; 
    // size it to be 100 px wide, and the correct 
    // height for its aspect ratio 
    img.style.width = "100px"; 
    img.style.height = ((height/width)*100) + "px"; 
    document.body.appendChild (img); 
    }; 

    ImageLoader.loadImage (callback, 
    "http://upload.wikimedia.org/wikipedia/commons/thumb/" + 
     "1/19/Caerulea3_crop.jpg/800px-Caerulea3_crop.jpg", 1); 

    ImageLoader.loadImage (callback, 
    "http://upload.wikimedia.org/wikipedia/commons/thumb/" + 
     "8/85/Calliphora_sp_Portrait.jpg/402px-Calliphora_sp_Portrait.jpg", 2); 
+0

是的,它适用于客户端,甚至当你想从另一台服务器上“附加”一个映像时,但是当我连接速度很慢时(或者更糟糕的是,我以每MB支付的连接),我真的当我不得不下载大于1MB的超大图像时,会非常讨厌它,这实际上比图像要小很多,特别是当这些图像显示为缩略图时。而且,由于糟糕的(即对速度进行了优化)缩放算法,浏览器调整大部分图像看起来很糟糕。 – 2010-11-12 23:02:10

+0

Marcel你说得很好......我应该指出,在我使用我的图像加载器的地方,事情并不是为了调整图像大小,而是为了在屏幕上很好地定位它们,甚至可以在完全下载图像之前将它们动画化。而且我用这个应用程序来制作一个Facebook应用程序,我从facebook上绘制图片,之前无法分辨大小,因为它们不是来自我的服务器......这是让它看起来不错的唯一方法。 – rob 2010-11-12 23:09:37

0

有了你有你的代码设置,我会尝试从onload事件打电话给你的大小调整功能的方式。

function resize() { 
    var img = document.getElementById('currentImage'); 
    var maxh = 375; 
    var maxw = 655; 
    var ratio = maxh/maxw; 
    if (img.height/img.width > ratio){ 
    // height is the problem 
    if (img.height > maxh){ 
     img.width = Math.round(img.width*(maxh/img.height)); 
     img.height = maxh; 
    } 
    } else { 
    // width is the problem 
    if (img.width > maxw){ 
     img.height = Math.round(img.height*(maxw/img.width)); 
     img.width = maxw; 
    } 
    } 
}; 

function changeCurrentImage(conteneur) 
{ 
    var img = conteneur.getElementsByTagName("img"); 

    img.onload = resize; 

    var imgUrl = img[0].src; 

    var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9); 
    var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.')); 
    var currentImg = document.getElementById('currentImage'); 
    currentImg.src = imgFirstPart + "borne" + imgLastPart; 


} 

我会玩这个。也许使用全局变量为你的maxH/W和图像ID(s);

0

@评论:不,我不能做那个服务器端,因为每次有人点击一个新的图像时它会刷新页面。这对用户来说太麻烦了,烦人了。

至于缩略图,这些图像已保存在适当的大小。只有显示的大图大约占其大小的33%。由于我们已经上传了3张图片,因此我不想为每次上传上传第4张图片,这会占用太多的服务器空间!

至于 “currentImage”,我忘了补充,所以这可能是helful笑:

<div id="currentImageContainer">
<div id="currentImageContainer1">
<div id="currentImageContainer2">
<img id="currentImage" src="#" alt="" onload="resize(this, 375, 655)" />
</div>
</div>
</div>

@rob:我会尽力的ImageLoader的类,这可能做的伎俩。

+0

不,服务器端不必刷新页面。 [用于IIS的imageresizing.net模块](http://imageresizing.net)允许您使用图像查询字符串I.e'image.jpg?width = 100'调整图像大小。它只会刷新图像,不会重新加载页面,并且可以很容易地从javascript中更改图像URL。 – 2012-01-09 20:38:19

0

我发现了一个非常好的替代方案。相反,改变这种IMG的宽度和高度,我将其删除,并创建一个新的:

function changeCurrentImage(conteneur) 
{ 
    var thumbnailImg = conteneur.getElementsByTagName("img"); 

    var thumbnailImgUrl = thumbnailImg[0].src; 

    var newImgUrl = thumbnailImgUrl.replace("thumbnail", "borne"); 

    var currentImgDiv = document.getElementById('currentImageContainer2'); 
    var currentImg = currentImgDiv.getElementById("currentImage"); 
    if (currentImg != null) 
    { 
     currentImgDiv.removeChild(currentImg); 
    } 

    var newImg = document.createElement("img"); 
    newImageDiv = document.getElementById('currentImageContainer2'); 
    newImg.id = "currentImage"; 
    newImg.onload = function() { 
     Resize(newImg, 375, 655); 
     newImageDiv.appendChild(newImg); 
    } 
    newImg.src = newImgUrl; 
} 

此外,如果人们不知道,你必须把.onload前。src当分配一个新的图像源!