调整动态图像大小无法多次使用

发布于 2024-10-01 16:27:14 字数 1815 浏览 0 评论 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 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>

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

じее 2024-10-08 16:27:14

很可能图像尚未下载,因此 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);

Most likely the image is not yet downloaded so img.height and img.width are not yet there. 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.

Edit: add ImageLoader utility:

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);
花伊自在美 2024-10-08 16:27:14

根据您的代码设置方式,我会尝试从 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;

With the way you have your code setup, I would try and call your resize function from an onload event.

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

_畞蕅 2024-10-08 16:27:14

@Comments:不,我不能在服务器端执行此操作,因为每次有人单击新图像时它都会刷新页面。这对用户来说太麻烦和烦人了。

至于缩略图,这些图像已经以适当的尺寸保存。仅显示的大图像约为其大小的 33%。由于我们每张上传的图像已经有 3 张图像,我不想每次上传都上传第 4 张图像,那样会占用太多的服务器空间!

至于“currentImage”,我忘了添加它,所以这可能会有帮助,哈哈:

@rob:我将尝试 ImageLoader 类,这可能会解决问题。

@Comments: No, I can't do that server side since it would refresh the page everytime someone click on a new image. 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. 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!

As for the "currentImage", I forgot to add it, so that might be helful lol:

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

胡渣熟男 2024-10-08 16:27:14

我找到了一个效果非常好的替代方案。我没有更改 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 之前!

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:

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文