blueimp/JavaScript-Load-Image

Breaking change in prev release

BrodaNoel opened this issue · 1 comments

Hi everyone.
I can't find in which commit you had it, but... check this out:

During... I guess years, we have been using this code in my company's project:

  fixImageRotation = file => {
    return new Promise(resolve => {
      loadImage(
        file,
        img => {
          img.toBlob(blob => {
            resolve(blob);
          }, 'image/jpeg');
        },
        { orientation: true }
      );
    });
  };

Seems like some weeks/months ago, this feature stoped working (it's a feature we don't frecuently use, so, we are not sure when it got broken).

The bug was simple: img.toBlob is undefined.
I had to dig a lot inside your code (forked, and running tests), where I realized that in this test, you ALSO have it undefined:

    it('Load image url as img element', function (done) {
      expect(
        loadImage(imageUrlGIF, function (img) {
          console.log('$$ img.toBlob', img.toBlob); // <<< Here is undefined
          expect(img.nodeName.toLowerCase()).to.equal('img')
          expect(img.width).to.equal(60)
          expect(img.height).to.equal(40)
          done()
        })
      ).to.be.ok
    })

So, after 3 millon console.log, I realized that here, you do have it defined:

    it('Write EXIF Orientation tag and replace image head', function (done) {
      loadImage(
        blobJPEG,
        function (img, data) {
          console.log('$$ what img.toBlob', img.toBlob); // <<< Here it's defined.
          expect(data.imageHead).to.be.ok
          expect(data.exif).to.be.ok
          expect(data.exif.get('Orientation')).to.equal(6)
          expect(data.iptc).to.be.ok
          expect(data.iptc.get('ObjectName')).to.equal('blueimp.net')
          // Reset EXIF Orientation data:
          var buffer = loadImage.writeExifData(
            data.imageHead,
            data,
            'Orientation',
            1
          )
          // Check if Orientation writer changes image head buffer in place:
          expect(buffer).to.equal(data.imageHead)
          img.toBlob(function (blob) {
            loadImage.replaceHead(blob, data.imageHead, function (newBlob) {
              loadImage(
                newBlob,
                function (img, data) {
                  expect(img.width).to.equal(40)
                  expect(img.height).to.equal(60)
                  expect(data.imageHead).to.be.ok
                  expect(data.exif).to.be.ok
                  expect(data.exif.get('Orientation')).to.equal(1)
                  expect(data.iptc).to.be.ok
                  expect(data.iptc.get('ObjectName')).to.equal('blueimp.net')
                  done()
                },
                { meta: true }
              )
            })
          }, 'image/jpeg')
        },
        { meta: true, orientation: true, canvas: true, minWidth: 40 }
      )
    })

Soooo, I added the { canvas: true } option, and now it's fixed in the project.

The problem, is that it is a breaking change. Which is probably the root of the problem of blueimp/JavaScript-Canvas-to-Blob#35.
That's just another dev that didn't add the canvas: true, so .toBlob is undefined.

As you may image, I fixed it doing this:

  fixImageRotation = file => {
    return new Promise(resolve => {
      loadImage(
        file,
        img => {
          img.toBlob(blob => {
            resolve(blob);
          }, 'image/jpeg');
        },
        {
           orientation: true,
           canvas: true, // <<< Here the fix
         }
      );
    });
  };

Hi @BrodaNoel and sorry for the late reply.
I think what you are referring to is a breaking change that happened in browsers - browsers updated their logic on the auto-orientation of images, now doing it automatically.
As a result, images that had to be returned as canvas objects to be able to adjust their orientation now could be returned as is, without converting them into canvas elements first.
The possibility that the library might return and img element was always there and documented:
https://github.com/blueimp/JavaScript-Load-Image#callback-arguments