简体   繁体   English

调整动态图像的大小不可用一次以上

[英]Resizing dynamic images not working more than one time

I've got a little problem here. 我这里有一个小问题。 I've been trying to do an image gallery with JavaScript but there's something that I got a problem with. 我一直在尝试使用JavaScript创建图片库,但是我遇到了一些问题。 I can get the image to resize when the first image load, but as soon as I load another image, it won't resize anymore! 我可以在加载第一个图像时调整图像的大小,但是一旦加载另一个图像,就不会再调整大小了! Since the user will be able to upload a lot of different size pictures, I really need to make it work. 由于用户将能够上传许多不同尺寸的图片,因此我真的需要使其工作。

I've checked for ready-to-use image gallery and such and nothing was doing what I need to do. 我已经检查了现成的图片库,并且没有做任何我需要做的事情。

Here's my 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;  
    }  
  } 
};

Here's the HTML (using ASP.Net Repeater): 这是HTML(使用ASP.Net Repeater):

<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>

Most likely the image is not yet downloaded so img.height and img.width are not yet there. 该图像很可能尚未下载,因此img.height和img.width尚不存在。 Technically you don't need to wait till the whole image is downloaded, you can poll the image in a timer until width and height are non-zero. 从技术上讲,您无需等到整个图像下载完毕,就可以在计时器中轮询图像,直到宽度和高度不为零为止。 This sounds messy but can be done nicely if you take the time to do it right. 这听起来很混乱,但是如果您花时间做对的话,可以很好地做到。 (I have an ImageLoader utility I made for this purpose....has only one timer even if it is handling multiple images at once, and calls a callback function when it has the sizes) I have to disagree with Marcel....client side works great for this sort of thing, and can work even if the images are from a source other than your server. (我有一个为此目的制作的ImageLoader实用程序。...即使一次处理多个图像也只有一个计时器,并在有大小时调用回调函数)我不得不不同意Marcel ....客户端对于这种事情非常有用,即使图像来自服务器以外的其他来源也可以正常工作。

Edit: add ImageLoader utility: 编辑:添加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;
      }
    }
};

Example usage: 用法示例:

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);

With the way you have your code setup, I would try and call your resize function from an onload event. 通过您的代码设置方式,我将尝试从onload事件中调用您的resize函数。

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;


}

I would play around with that. 我会玩的。 Maybe use global variables for your maxH/W and image ID(s); 也许对您的maxH / W和图片ID使用全局变量;

@Comments: No, I can't do that server side since it would refresh the page everytime someone click on a new image. @Comments:不,我无法在服务器端进行操作,因为每次有人单击新图像时,它都会刷新页面。 That would be way too bothersome and annoying for the users. 对于用户而言,这将太麻烦又烦人。

As for the thumbnails, those image are already saved in the appropriate size. 至于缩略图,这些图像已经以适当的尺寸保存。 Only the big image that shows is about 33% of its size. 仅显示的大图像约为其大小的33%。 Since we already have 3 images PER uploaded images, I didn't want to upload a 4th one for each upload, that would take too much server space! 由于每个上传的图像已经有3张图像,因此我不想为每次上传上传第4张图像,这将占用太多服务器空间!

As for the "currentImage", I forgot to add it, so that might be helful lol: 至于“ currentImage”,我忘了添加它,所以可能是很高兴的:

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

@rob: I'll try the ImageLoader class, that might do the trick. @rob:我将尝试ImageLoader类,这可能会解决问题。

I found an alternative that is working really well. 我找到了一种效果很好的替代方法。 Instead of changing that IMG width and height, I delete it and create a new one: 无需更改该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;
}

Also, in case people wonder, you MUST put the .onload before the .src when assigning an a new source for an image! 另外,以防万一,您在为图像分配新的源时必须将.onload放在.src之前!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM