Coder Social home page Coder Social logo

ericnograles / browser-image-resizer Goto Github PK

View Code? Open in Web Editor NEW
98.0 4.0 42.0 3.78 MB

A tiny browser-based library to downscale and/or resize images using canvas

License: MIT License

JavaScript 61.09% Shell 1.21% HTML 12.75% Vue 19.04% Nix 0.82% CSS 5.09%

browser-image-resizer's Introduction

browser-image-resizer

A tiny (~7kb uncompressed, ~1kb compressed) browser-based library to downscale and/or resize images using <canvas>.

Introduction

The code was part of Ross Turner's HTML5-ImageUploader. Note that this is meant to be a browser-only utility and will not work in Node.js.

Demo

Installation

NPM/Yarn

  • npm install browser-image-resizer
  • yarn add browser-image-resizer

Browser

<script src="https://cdn.jsdelivr.net/gh/ericnograles/[email protected]/dist/index.js"></script>

Usage

NPM/Yarn

Promises

import { readAndCompressImage } from 'browser-image-resizer';

const config = {
  quality: 0.5,
  maxWidth: 800,
  maxHeight: 600,
  debug: true
};

// Note: A single file comes from event.target.files on <input>
readAndCompressImage(file, config)
  .then(resizedImage => {
    // Upload file to some Web API
    const url = `http://localhost:3001/upload`;
    const formData = new FormData();
    formData.append('images', resizedImage);
    const options = {
      method: 'POST',
      body: formData
    };

    return fetch(url, options);
  })
  .then(result => {
    // TODO: Handle the result
    console.log(result);
  });

Async/Await

import { readAndCompressImage } from 'browser-image-resizer';

const config = {
  quality: 0.7,
  width: 800,
  height: 600
};

// Note: A single file comes from event.target.files on <input>
async function uploadImage(file) {
  try {
    let resizedImage = await readAndCompressImage(file, config);

    const url = `http://localhost:3001/upload`;
    const formData = new FormData();
    formData.append('images', resizedImage);
    const options = {
      method: 'POST',
      body: formData
    };

    let result = await fetch(url, options);

    // TODO: Handle the result
    console.log(result);
    return result;
  } catch (error) {
    console.error(error);
    throw(error);
  }
}

Browser

Promises

const config = {
  quality: 0.5,
  maxWidth: 800,
  maxHeight: 600,
  debug: true
};

// Note: A single file comes from event.target.files on <input>
BrowserImageResizer.readAndCompressImage(file, config)
  .then(resizedImage => {
    // Upload file to some Web API
    const url = `http://localhost:3001/upload`;
    const formData = new FormData();
    formData.append('images', resizedImage);
    const options = {
      method: 'POST',
      body: formData
    };

    return fetch(url, options);
  })
  .then(result => {
    // TODO: Handle the result
    console.log(result);
  });

Async/Await

const config = {
  quality: 0.7,
  width: 800,
  height: 600
};

// Note: A single file comes from event.target.files on <input>
async function uploadImage(file) {
  try {
    let resizedImage = await BrowserImageResizer.readAndCompressImage(file, config);

    const url = `http://localhost:3001/upload`;
    const formData = new FormData();
    formData.append('images', resizedImage);
    const options = {
      method: 'POST',
      body: formData
    };

    let result = await fetch(url, options);

    // TODO: Handle the result
    console.log(result);
    return result;
  } catch (error) {
    console.error(error);
    throw(error);
  }
}

readAndCompressImage(file, config) => Promise

Inputs

  • file: A File object, usually from an <input>
  • config: See below
Property Name Purpose Default Value
quality The quality of the image 0.5
maxWidth The maximum width for the downscaled image 800
maxHeight The maximum height for the downscaled image 600
autoRotate Reads EXIF data on the image to determine orientation true
debug console.log image update operations false
mimeType specify image output type other than jpeg 'image/jpeg'

Outputs

A Promise that yields an Image Blob

Contributing

The fastest way to contribute back is to fork the repl.it of this repo (https://replit.com/@grales/browser-image-resizer). Please open any Issues if you have trouble spinning it up.

repl.it First-time Setup

Upon forking of the repl.it, open a new Shell and follow these instructions:

  1. Execute npm link at the top ~/browser-image-resizer folder
  2. Execute cd tests/bir-vue
  3. Execute npm i && npm link browser-image-resizer && npm run serve
  4. Your repl.it should automatically boot to a webview of a Vue 3 CLI SPA
  • This SPA will point to your built copy of browser-image-resizer that runs automatically when the repl.it boots
  1. Modify any code at the top level src/ and it will reflect on your Vue 3 CLI SPA test app

repl.it Specifics

  • The repl.it above is configured to run the dev script of the library, which is a webpack-dev-server that auto-generates the dist/ library which is the entry point of this library
  • The subsequent commands gives you an actual web application on which to verify your changes
  • If you prefer, you can do this locally as well, but the repl.it ensures a faster and more consistent onboarding

browser-image-resizer's People

Contributors

alechstong avatar danleininger avatar dependabot[bot] avatar ericnograles avatar jasonkit avatar jperasmus avatar otaviosoares avatar qwazwsx avatar watercycle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

browser-image-resizer's Issues

Syntax error in IE11 in version 2.1.0

Hello,

Since version 2.1.0 IE11 throws a syntax error when executing the plugin.

To reproduce it's enough to copy the code from dist/index.js and paste in the IE11 console.

I am not sure if this is something related with the new depedency exifreader that was added with 2.1.0 or something else.

If there is anything else I can to help, just let me know.

Thanks for your work.

Have a nice week!

Just thanks

Spent hours finding a browser image resizing library.

Too much upload libraries re-invented the wheel like plupload or dropzonejs, some of them are too overkill and can only manipulate canvas like pica, moreover https://github.com/rossturner/HTML5-ImageUploader was a lazy and upload oriented repo with no npm distribution since years.

Thanks a lot for your work, don't hesitate to open this repo to other admin contributors ;)

Image upload failed whenever autoRotate is false false

    quality: 0.5,
    maxWidth: 800,
    maxHeight: 600,
    autoRotate: false,

I am using this config and unable the complete . when autoRotate is set to false readAndCompressImage's promise is not finishing . But when autoRotate is set true it is working.

Canvas Area Exceeds Maximum Limit on iOS Safari

Issue: Canvas Area Exceeds Maximum Limit on iOS Safari

Description

When attempting to resize large images on iOS using Safari, the process fails due to the browser's limitations. Specifically, this issue arises because Safari restricts the canvas area to a maximum size (width * height > 16777216). As a result, resizing large images leads to failures, often resulting in a black image being sent to the server.

Steps to Reproduce

  1. Open Safari on an iOS device.
  2. Attempt to resize a large image (e.g., an image with dimensions that exceed the maximum canvas area).
  3. Observe the failure and the resulting black image.

Expected Behavior

Large images should either:

  • Not be resized if the canvas size exceeds the maximum limit.
  • Be resized using an alternative method that does not rely on the canvas.

Actual Behavior

The resizing process fails, and a black image is sent to the server.

Suggested Solution

Implement a check for the canvas size before resizing. If the size exceeds the limit, either:

  • Skip the resizing process, or
  • Use a different resizing method that does not involve the canvas.

Additional Information

While resizing images before uploading is typically desired, it is preferable to avoid sending a black image due to resizing issues. This solution aims to provide a more graceful fallback for handling large images in Safari on iOS.

BUG: It depends on vulnerable versions of exifreader, forcing the fix to version 2.0.1 breaks the lib.

npm audit report

xmldom *
Severity: moderate
Misinterpretation of malicious XML input - GHSA-5fg8-2547-mr8q
Misinterpretation of malicious XML input - GHSA-h6q6-9hqw-rwfv
fix available via npm audit fix --force
Will install [email protected], which is a breaking change
node_modules/xmldom
exifreader 2.7.0 - 3.16.0
Depends on vulnerable versions of xmldom
node_modules/exifreader
browser-image-resizer >=2.1.0
Depends on npm audit report

xmldom *
Severity: moderate
Misinterpretation of malicious XML input - GHSA-5fg8-2547-mr8q
Misinterpretation of malicious XML input - GHSA-h6q6-9hqw-rwfv
fix available via npm audit fix --force
Will install [email protected], which is a breaking change
node_modules/xmldom
exifreader 2.7.0 - 3.16.0
Depends on vulnerable versions of xmldom
node_modules/exifreader
browser-image-resizer >=2.1.0
Depends on vulnerable versions of exifreader
node_modules/browser-image-resizer

3 vulnerabilities (2 low, 1 moderate)
node_modules/browser-image-resizer

3 vulnerabilities (2 low, 1 moderate)

here is a listing of all installed packages:

+-- @quasar/[email protected]
+-- @quasar/[email protected]
+-- @vueuse/[email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
`-- [email protected]

CDN link broke suddenly

I am currently maintaining an ionic v1 cordova application where this library is used. It is imported using the CDN script link provided in the README https://cdn.jsdelivr.net/gh/ericnograles/[email protected]/dist/index.js.
It was working perfectly until it suddenly broke halting the whole application from starting up.

Is there any way to fix this ASAP?

Nextjs ReferenceError: self is not defined

Everything works well till i deploy the app and the code is building on Vercel or Netlify and then i get the
ReferenceError: self is not defined

below is my import code and what is compressed

'use client';

import "./forminput.css";
import { useState, useRef } from 'react';
import { readAndCompressImage } from 'browser-image-resizer';


const SingleImageUploadInput = ({ children }) => {
    const readImage = async (file) => {
        const config = {
            quality: 0.7,
            maxWidth: 1920,
            maxHeight: 1080,
            mimeType: 'image/webp',
            debug: true,
        };
        
        try {
            const resizedImageFile = await readAndCompressImage(file, config);
            const reader = new FileReader();
            
            return new Promise((resolve, reject) => {
                reader.onloadend = () => {
                    resolve(reader.result);
                };
                reader.onerror = reject;
                reader.readAsDataURL(resizedImageFile);
                let resizedImgSize = resizedImageFile.size;
                setImageSize(convertFileSize(resizedImgSize));
            });
        } catch (error) {
            console.log('Failed to resize the image:', error);
        }
    };

Quick Crop

Thanks for this lib! :)

Is it hard to implement a quick crop based on options width/height and center on the image?

Thanks!

Add directions for static generation usage

When using this library for SSG scenarios like NextJS, it's necessary to use a dynamic import otherwise the build fails with self is not defined.

For NextJS, this looks like the following:

const { readAndCompressImage } = (await import('browser-image-resizer'));

This is because the static generation doesn't have access to the browser context. Otherwise it works great!

Transparency replaced with white

When processing a PNG with transparency, the transparency is removed and replaced with a white background, even when the mimeType is set to PNG in the config.

This seems to be caused by the fix for #42, PNGs retain their transparency in the previous version.

NodeJS https module dependency in latest version

Hi,

thanks for this package.

I'm using it in a React app with the standard create-react-app config. Since version v2.2.1 of browser-image-resizer, the React app doesn't compile with the following error:

ERROR in ./node_modules/browser-image-resizer/dist/index.js 3476:52-72

Module not found: Error: Can't resolve 'https' in '/Users/user/dev/frontend-futura/node_modules/browser-image-resizer/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }'
	- install 'https-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "https": false }

I understand the error and know how to fix it, but I was wondering if it's necessary to have this https depedency that requires me to add a polyfill.

Thanks for your time

Doesn't work on Wkwbview

This library doesn't seem to work on wkwebview (capacitor / cordova / ionic app).

Debug doesn't throw any log / error when passing a file to resizeAndCompressImage

Maybe you use APIs not available on wkwebview

Do you plan to fix it ?

Incorrect image transformation for few EXIF orientations

The problem is reproduced on any version of the module.

I tested auto-rotation using an image with all possible EXIF orientations and found that some of them are not handled (transformed) correctly.

Here is a list of EXIF orientations from my tests with handle results and original image without EXIF orientation:

ID Orientation Image Correctly transformed
1 Horizontal (normal) orientation-1 โœ”๏ธ
2 Mirror horizontal orientation-2 โœ”๏ธ
3 Rotate 180 orientation-3 โœ”๏ธ
4 Mirror vertical orientation-4 โœ”๏ธ
5 Mirror horizontal and rotate 270 CW orientation-5 โœ”๏ธ
6 Rotate 90 CW orientation-6 โŒ
7 Mirror horizontal and rotate 90 CW orientation-7 โœ”๏ธ
8 Rotate 270 CW orientation-8 โŒ

Larger file size than inputted file.

I'm using these settings:

const imageResizerConfig = {
  quality: 1,
  maxWidth: 3000,
  maxHeight: 3000,
  autoRotate: true,
  debug: true
};

and when I load an image that is below the max dimensions, I am seeing the end result become double the size of the original file.

For example, a png file has the original size of 130930 bytes. When I put it through readAndCompressImage and create a new file (using File API) from the returned blob I am seeing a new file size of 230394 bytes.

Could you explain this please?

Unable to readAndCompressImage multiple images at once

I am trying to resize an array of images, and it seems that some or all of the promises never resolve. This was working in version 2.1.0 but is no longer working in 2.1.3.

My code:

const getResizedImage = async image => {
  return await readAndCompressImage(image, {
    quality: 0.7,
    maxWidth: 766,
    maxHeight: 476,
    mimeType: "image/png"
  });
};

const images = [file, file, file];

const resizedImages = await Promise.all(images.map(image => getResizedImage(image)))

This seems to work if the images array only has a single file in it, but if I pass 2 or more files, await Promise.all never resolves.

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.