Giter Site home page Giter Site logo

fengyuanchen / compressorjs Goto Github PK

View Code? Open in Web Editor NEW
5.1K 40.0 436.0 762 KB

JavaScript image compressor.

Home Page: https://fengyuanchen.github.io/compressorjs/

License: MIT License

JavaScript 99.82% Shell 0.18%
javascript image-compression image-compressor file-upload

compressorjs's Issues

Why this code doesn't compress the image?

minWidth e minHeight are not working

new ImageCompressor(event.target.files[0], {
    maxWidth: 300,
    maxHeight: 300,
    success(result) {
        new S3('guizion-futtari', this).uploadFile('translator-profile', result, (url) => {
            self.photoUrl = url
            console.log(url)
            self.updateUser()
        }, (error) => {
            console.error(error)
            self.loading = false
        })
    },
    error(e) {
        console.log(e.message)
    },
})

Failed to load the image

I got this error message,when i compressed image on one android mobile phone.
The code runs rightly with other phones.

Feature request - give heavier tasks a separate thread

First of all great job on creating this image-compressor, I love it!

I was wondering if it could be made even more efficient by putting the heavier tasks of compressing an image in a separate thread (for example with webworkers, though this example can be a lot of work with workers having no access to the DOM).

The reason for this idea is that when using this compressor in a web based application I noticed that the page freezes temporarily when processing an image on a phone and with very large images even a computer can freeze for a few seconds.

I hope this is an idea interesting enough to be worth pursuing!

Make size smaller by converting to grayscale

For a given fixed size and fixed quality (let's say 0.8), is it possible to reduce file size even further / save even more kB by saivng the image as grayscale JPG?

How to do that @xkeshi?

What additional % reduction can we hope by discarding color and going grayscale (in general)?

Image Compressor Safari(?)

I can't get this to work on Safari at all.
Safari seemingly executes new ImageCompressor(file, { [options], succes(){...}, error(){...} });
Then, Safari simply continues executing the code after as if new ImageCompressor returned already. No success code is executed. no error code is executed.

Again, this is no problem on other browsers/devices.
I don't know what the cause of the issue is. Any help is appreciated. Code below.

Small black line in picture's bottom after compression

I use this library to compress images to a max file size of 70kb before uploading it to AWS S3. I do it twice: one time for my main higher quality image and another time to generate a thumbnail of the same image.

In some cases, randomly and after conversion, the images comes out with a small black line in the bottom of the image. There's one example in here: https://s3-sa-east-1.amazonaws.com/carpediemxp-test-0000001/partners-pictures-thumb/5b528fc884f90700148ec69a

In most cases this does not happen, but when it does, it's really annoying, because images are the main attractions of my web service.

I suspect this may happen because of image dimensions floating point approximations while converting the image from one size to another, but I don't know how to fix this.

Is there any way to fix this problem and keep my images without those black lines?

Thanks in advance!

Filename always returns blob

after append data to multipart it always return data with filename "blob" without any extension. how to send filename as original filename in result object.

What if it is used in multiple uploads?

can you help me?

var files = [];
var formData = new FormData();

document.getElementById('file').addEventListener('change', (e) => {
const file = e.target.files;

if (!file) {
   return;
}
  
var filesLength = file.length;

for (var i = 0; i < filesLength; i++) {
    new ImageCompressor(file[i], {
      quality: .6,
      maxWidth: 2000,
      maxHeight: 2000,
      success(result) {
        formData.append('files[]', result, result.name);
      },
      error(e) {
        console.log(e.message);
      },
    });
  }
});

$( "#upload" ).click(function() {
  axios.post('path', formData).then(() => {
        console.log('Upload success!');
  });
});

From the script above, I can get the picture. but can not get his name.
Can you help me? :D

Images after compressing cannot be uploaded to Firebase

Hello, I have an issue with compressing images before uploading to Firebase. Firstly, my original code to upload a list of images to Firebase works (below)

        const images = await FirebaseSevice.uploadMissionImage(imageFiles);

However, I need to compress images before uploading to improve the performance of my application, so I use this library but I cannot upload processed images to Firebase. My code uses xkeshi/image-compressor

      const IM = new ImageCompressor();
      let processed = [];
      for (let image of imageFiles) {
        IM.compress(image)
          .then((result) => {
            console.log(result);
            processed.push(result);
          });
      }
      const images = await FirebaseSevice.uploadMissionImage(processed);

PS: FirebaseSevice.uploadMissionImage() takes a array of files as a parameter
Do you have any solution for this case?
Thanks.

iOS 9 Invalid attempt to spread non-iterable instance

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x ] Bug report 
[ ] Feature request
[ ] Documentation issue or request

Current behavior

iOS9 设备上的 Safari 始终报 “Invalid attempt to spread non-iterable instance” 错误

调试后发现 _arrayWithoutHoles 方法中的 Array.isArray() 返回 false,移除这个判断后不报错了,怀疑是 iOS9 的把数组误判断为不是数组。

改成这样后功能正常了:

function _toConsumableArray(arr) {
  return _iterableToArray(arr) || _arrayWithoutHoles(arr) || _nonIterableSpread();
}

function _arrayWithoutHoles(arr) {
  for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];

  return arr2;
}

Expected behavior

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Compressor.js version: X.Y.Z


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [x] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX

Others:

Cant change image name or convert into png image-compressor ignores options...

I cant change image name or convert into png

I am using

const imageCompressor = new ImageCompressor();

imageCompressor.compress(file, {
          mimeType: 'image/jpeg',
          quality: 0.7,
          maxWidth: 1280,
          maxHeight: 900,
          checkOrientation: true,
          mimeType: 'image/jpeg',
})
  .then((result) => {
    result.name = 'specific-name.jpg';
    // ...
  });

The image I am trying is a 398 × 326 .png but always retuns as png image and name doesnt get changed either..

But it works on a .jpg image, and if I try to convert bigger .png image (1920 × 1200) it also works. Is seems really odd to me.

I have also tried convertSize: 1, in order to force convertion but with no luck..

Test image:

111111111111

to base64?

Could you export the result to base64?

Compress multiple images

I am compressing multiple images.

I have up to 25 images in a array.
I loop through all images then call new ImageCompressor() for each image. Is there any other way to compress multiple images at? I dont feel like my way is very thread safe

image orientation?

Have you considered adding a check for image orientation? Or an option to leave exif data? I am doing more image work on the server with sharp, which has an autorotate feature, but the if I run the file through this on the client first, sharp will have no exif data to autorotate with. This is mostly an issue with images people upload via their iphone.

A similar package to this, import loadImage from 'blueimp-load-image', has a rotate feature.

I'll look at exif-js or something else to maybe pre-pre-process it, but it'd be awesome to just pass in an extra option to image-compressor.

Options can be improved

There are some issues in the part of the code which handles resizing:

  • options.height is ignored when options.width is set;
  • and images smaller than options.height and/or options.height can be either upscaled or not compressed (because the comparison in line 107);

Note that, because the comparison in line 107, seems resizing is only a method to try to make a image smaller, not a requirement. I think there should be at least a note in readme about that.

In lines 94 and 96 the format of the resulting image is the same format of the original image. So the format is a choice of the end user (it can be even a BMP image). Would be better if it was an option.

Finally, is complicated to add a size limit option? Too large files can be compressed into a lossy format (like imgur, which converts PNGs larger than 5MB to JPEG).

[iOS]Safari: The operation is insecure

I used in iphone safari , iOS 11.2,
but throw this error, I've tried to solve this error,
I add this code to image-compressor.esm.js in line 627

image.setAttribute('crossOrigin', 'anonymous');

the error gone

Returned type is not detectable

After compressing, image result returns Blob or File just like docs says!
There doesn't seem to be an option for result type on docs. Is there a way to detect or infer type rather than below snippet?

result.__proto__.constructor.name

npm 1.1.4

Hello, could you push the new release on NPM please ?

Note about: quality / compression setting

As, in general, it is a good thing to compress images, it may be counter productive in some cases.
Compressing images before uploading is useful if the images later on are served 'as-is' by a website, for example. But it isn't, if the images are sources for creation of image variations, like with a CMF or CMS. For the later, it is best usage to upload the images, (that serve as original source for variation creation), in the best possible quality. (uncompressed!)

Why is this correct?
If you create variations, the images get loaded into memory, unpacked / uncompressed, and get compressed on save again. This makes every previuos compression useless. But it isn't only useless, it also has some disadvantages, when working with previously compressed images.

Please try and compare two images:

  • A = uncompressed uploaded source, filesize = 2 MB (for example)
  • B = compressed uploaded same source, filesize = 1.1 MB (for example)

Workflow for both images is to create a halfsized variation, with e.g. PHP and GD-Library, save it, or save it and additionally pass it through a server side compressor, like image-optim.

Result will be:

  • A: filesize, for example, 0.6 MB
  • B: filesize, for example, 0.7 MB

Regardless if there is an extra compression tool involved or not, the final filesize of the B-file will be always greater then that of the A-file. Also the visual quality of the B image is of lesser quality, means it will have more (JPEG) artifacts.

So, when using this library for images uploaded into a CMF / CMS for later variation creation, everytime a quality setting of 1 should be used. This is highly recommended!

The strong and very useful part of the library in case of CMF / CMS is the possibilty to resize the images before uploading, means, they should not exceed some maximum dimensions in most cases! This helps in saving bandwidth and time for uploading the images and also in server-side saving of time and cpu- and memory-usage later on with every variation creation in the CMF / CMS!

Simple example

Please provide a simple example using jQuery. It is difficult to follow your examples. Thanks

IE11 - Invalid argument 'url'. Failed to revoke Blob URL: '..' with checkOrientation as true

I'm using the following config for compress:

var imageCompressorOptions = {
checkOrientation: true,
minWidth: 0,
minHeight: 0,
quality: 0.5,
mimeType: "",
convertSize: 5000000
};

And the following check:
if (URL) {
URL.revokeObjectURL(image.src);
}
Should be:
if (URL && !options.checkOrientation) {
URL.revokeObjectURL(image.src);
}
The same as is that check when need to create a blob URL.

What does convertSize do?

First off, thanks for sharing this lib!

I wonder what convertSize does? Does it have something to do with compression and how is it then different from the quality option?

Thanks

bug in v1.1.1 removing browser and adding unpkg is causing a not a constructor error

In v1.1.1

I saw that you removed "browser": "dist/image-compressor.js",
and added "unpkg": "dist/image-compressor.js",

This gives me the error
ImageCompressor is not a constructor when I use it like this:

window.ImageCompressor = require('image-compressor.js');
var imageCompressor = new ImageCompressor();

However if I add the line "browser": "dist/image-compressor.js", to image-comrpressors package.json file the code works fine

I am using this package in a laravel/webpack project

Error: The first argument must be a File or Blob object.

Hi,

I'm working on Angular 4, Ionic 3, Cordova application.

I'm getting this error when passing a File to new ImageCompressor(file, options)

This is my implementation:

window.resolveLocalFileSystemURL(path, (fileEntry) => {
      fileEntry.file((file) => {
        console.log(file)

          new ImageCompressor(file, {
            quality: 0.6,
            success: (result) => {
              console.log(result, result.size)
            },
            error: err => {
              console.log(err)
            }
          })
      })
    }, err => {
      console.log(err)
    });

I even tried reading this file as ArrayBuffer (readAsArrayBuffer(file)), which returns a blob and passing the same to ImageCompressor, but it did not help.

The console.log(file) returns me this:

File
end: 285885
lastModified: 1515080323747.9968
lastModifiedDate: 1515080323747.9968
localURL: "cdvfile://localhost/temporary/cdv_photo_016.jpg"
name: "cdv_photo_016.jpg"
size: 285885
start: 0
type: "image/jpeg"

It'll be great if you can let me know, where I'm going wrong?

Thanks,

Receiving an error when i have options.checkOrientation set and the image isn't loaded via url

When i set the options to checkOrientation to false and the browser supports both URL/FileReader then the URL option is always used, even if the passed file cannot be resolved via an url, which results then in an error due to URL.createObjectURL(file) generating an Blob with an empty data.url. I think that this is not supposed to happen. If i have checkOrientation set to true, then everything works as it should.

Passed File:

lastModified:1492945785394
lastModifiedDate:Sun Apr 23 2017 13:09:45 GMT+0200 (W. Europe Daylight Time) {}
name:"79c628d31c50eb447a840f6e1ee9b6bb.jpg"
preview:"blob:http://localhost:5000/273d41e3-082a-4312-8109-210ee52ee4fc"
size:41563
type:"image/jpeg"
webkitRelativePath:""

Passed Data value generated from URL.createObjectURL(file):

blob:http://localhost:5000/295ce5f1-d966-4ada-a9a6-38f87692e12b

[Error]Safari: The operation is insecure.

Thanks for xkeshi, this tool works well on chrome, but in safari throws an error on this line:
canvas.toBlob(resolve, options.mimeType, options.quality);

anyone has any idea about this ? Here is my code:

const file = (<HTMLInputElement>document.getElementById('pic' + target)).files[0];
const compress = new ImageCompressor(file, {
        convertSize: 1000000,
        maxWidth   : 768,
        maxHeight  : 768,});

RangeError: Offset is outside the bounds of the DataView

Hi, i'm coming up with this error when i using image-crompressor with ngModel value (other cases work normal)
ERROR RangeError: Offset is outside the bounds of the DataView at DataView.getUint8 (<anonymous>) at getOrientation (image-compressor.esm.js:352) at FileReader.reader.onload (image-compressor.esm.js:611) at ZoneDelegate.invoke (zone.js:388) at Object.onInvoke (core.js:4760) at ZoneDelegate.invoke (zone.js:387) at Zone.runGuarded (zone.js:151) at FileReader.eval (zone.js:129)

and at GetOrientation leads me to
if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { var length = dataView.byteLength; var offset = 2;

Do you have any idea how to fix this? Thank you

Unable to install

I have shared hosted and cannot npm install. What other options are available?

How get original name from fromData?

I can get file image data
but i can't get original name image.

You can help me to get original name from image file?
I send data with formData.append('file', result, result.name);

Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.