jwagner / smartcrop.js

Content aware image cropping
http://29a.ch/2014/04/03/smartcrop-content-aware-image-cropping
MIT License
12.84k stars 577 forks source link

IndexSizeError: Index or size is negative or greater than the allowed amount smartcrop.js:282:0 #27

Closed rcanessa89 closed 8 years ago

rcanessa89 commented 8 years ago

That happend in Firefox and Safari, in Chrome is working properly for me

jwagner commented 8 years ago

Please provide a link to a page that allows me to reproduce this issue.

jwagner commented 8 years ago

No answer -> closing the issue.

simanacci commented 2 years ago

Update: I removed the script tag referencing the local .js file and it works, although I'm now getting a different error. Uncaught TypeError: callback is not a function smartcrop.js 119:13

@jwagner I'm experiencing the same issue on Firefox. Uncaught DOMException: Index or size is negative or greater than the allowed amount - smartcrop.js 324

<img id="profile-photo" src="https://test.s3.amazonaws.com/profile_photo/test.jpg" alt="Profile Photo" >
<script type="text/javascript" src="/static/smartcrop.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/smartcrop/0.0.0/smartcrop.js"></script>
<script type="text/javascript">
    window.addEventListener('DOMContentLoaded', function() {
        const image = document.getElementsByTagName("img").item(0);
        console.log(image);
        SmartCrop.crop(image, { width: 100, height: 100 }).then(function(result) {
            console.log(result);
        });
    }, false);
</script>
jwagner commented 2 years ago

@simanacci I'm not sure why you are using version 0.0.0 in 2022. ;) Anyways make sure that the image is complete before passing it to smartcrop (wait for onload to fire).

simanacci commented 2 years ago

@jwagner I had changed that but, it's still not working. https://gist.github.com/simanacci/b6736f9cc41135d6b8016fd1d5d672ce

jwagner commented 2 years ago

@simanacci complete is set to true after the image has been loaded. What the code above is doing is checking if the image has already finished loading and if it is already finished it waits for onload (which will never come). If you can avoid loading the image via HTML something like the async function loadImage(url, elem) on the complete mdn page referenced above is probably going to be more robust since even failed images are complete. It's all a bit of a mess. :)

jwagner commented 2 years ago

@simanacci actually on second though, if you just swap out domcontentloaded with load that should already do the trick. Let me know if that helps or if the problem persists.

simanacci commented 2 years ago

@jwagner After console.log(SmartCrop);, the function does nothing. https://postimg.cc/bZgY0HVc

<img id="profile-photo" alt="Politician Profile Photo" >
<script src="https://cdnjs.cloudflare.com/ajax/libs/smartcrop/2.0.5/smartcrop.js"></script>
<script type="text/javascript">
  const elem = document.getElementsByTagName("img").item(0);
  function smartCropper(photo) {
      console.log(photo);
      console.log(SmartCrop);
      SmartCrop.crop(photo, {
          width: 100,
          height: 100,
          minScale: 1.0
      }).then(function(result) {
          console.log(result);
          console.log(result.topCrop);
          console.log(result.topCrop.height);
          console.log(result.topCrop.width);
          image.style.width = result.topCrop.width + "px";
          image.style.height = result.topCrop.height + "px";
      });
  }
  async function loadImage(url, elem) {
      return new Promise((resolve, reject) => {
          elem.onload = () => resolve(smartCropper(elem));
          elem.onerror = reject;
          elem.src = url;
      });
  }
  async function getImage(url) {
      await loadImage(url, elem);
      console.log("Done!!");
      console.log(elem.complete);
  }
  const url = "https://test.s3.amazonaws.com/profile_photo/test.jpg";
  getImage(url);
</script>

@simanacci actually on second though, if you just swap out domcontentloaded with load that should already do the trick. Let me know if that helps or if the problem persists.

This didn't work.

jwagner commented 2 years ago

I get:

Uncaught (in promise) ReferenceError: image is not defined
    at simanacci.html:17:7

Which makes sense since there isn't any image to write to. Another thing to keep in mind is that if the image in question comes from a different origin (say your website is example.com and the image is loaded from test.s3.amazonaws.com) it needs to be CORS cleared so that smartcrop can read it's pixels.

I've added a more minimal example to the repo, maybe that helps you to get started.