All Projects → dfa1234 → ngx-image-compress

dfa1234 / ngx-image-compress

Licence: MIT license
Angular library for uploading and compressing images

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language
HTML
75241 projects
SCSS
7915 projects

Projects that are alternatives of or similar to ngx-image-compress

srcset.sh
A command line script that generates multiple responsive versions of an image at width breakpoints -- 320,480,640,768,960,1024,1280,1440 pixels wide -- that match common Mobile and widescreen desktop/laptop viewports using Imagemagick's convert utility and outputs the needed <img/> tag
Stars: ✭ 20 (-69.23%)
Mutual labels:  compression
x-compressor
x – minimalist data compressor
Stars: ✭ 42 (-35.38%)
Mutual labels:  compression
ndzip
A High-Throughput Parallel Lossless Compressor for Scientific Data
Stars: ✭ 19 (-70.77%)
Mutual labels:  compression
tiny
compress data for better performance
Stars: ✭ 21 (-67.69%)
Mutual labels:  compression
LittleBit
LittleBit is a pure Huffman coding compression algorithm with the option of random access reading while offering competitive compression ratios.
Stars: ✭ 13 (-80%)
Mutual labels:  compression
box
Box - Open Standard Archive Format, a zip killer.
Stars: ✭ 38 (-41.54%)
Mutual labels:  compression
zpacker
very simple LZ77-based compression
Stars: ✭ 15 (-76.92%)
Mutual labels:  compression
django-brotli
Django middleware that compresses response using brotli algorithm.
Stars: ✭ 16 (-75.38%)
Mutual labels:  compression
upx
Node.js cross-platform wrapper for UPX - the ultimate packer for eXecutables.
Stars: ✭ 27 (-58.46%)
Mutual labels:  compression
vue2-multi-uploader
Drag and drop multiple file uploader with Vue.js v2 and Axios
Stars: ✭ 46 (-29.23%)
Mutual labels:  upload-images
JFileSync3
File Syncing with encryption and compression (partly) compatible with encfs / boxcryptor (classic) volumes for local folders and WebDAV backends. Based on JFileSync - hence the name.
Stars: ✭ 20 (-69.23%)
Mutual labels:  compression
AndroidFlask
Image Upload from Android to Python-Based Flask Server
Stars: ✭ 45 (-30.77%)
Mutual labels:  upload-images
deflate-rs
An implementation of a DEFLATE encoder in rust
Stars: ✭ 47 (-27.69%)
Mutual labels:  compression
clp
Compressed Log Processor (CLP) is a free tool capable of compressing text logs and searching the compressed logs without decompression.
Stars: ✭ 49 (-24.62%)
Mutual labels:  compression
client-compress
A JavaScript based in-browser client-side image compression library
Stars: ✭ 32 (-50.77%)
Mutual labels:  compression
Perfect-Zip
Perfect Zip compression utility.
Stars: ✭ 20 (-69.23%)
Mutual labels:  compression
rocketjob
Ruby's missing background and batch processing system
Stars: ✭ 281 (+332.31%)
Mutual labels:  compression
sanic compress
An extension which allows you to easily compress your Sanic responses with gzip.
Stars: ✭ 26 (-60%)
Mutual labels:  compression
react-native-compressor
The lightweight library for compress image, video, and audio with an awesome experience
Stars: ✭ 157 (+141.54%)
Mutual labels:  compression
rust-huffman-compress
A Rust library for Huffman compression given a propability distribution over arbitrary symbols
Stars: ✭ 18 (-72.31%)
Mutual labels:  compression

ngx-image-compress

Angular utility for compressing images to a satisfying size, that you can choose

License Latest npm release NPM downloads Contributors

Build Status

Import

npm i ngx-image-compress

For visualizing code examples:
https://stackblitz.com/edit/ngx-image-compress

For performance tests, in particular tests on mobile, please do not use stackbliz, put rather this optimised demo, equivalent to what you get in a production-ready application:
https://image-library.app

Angular 13+ do not need any module import. Inject the service in the constructor of your component directly.
For any angular version before 13, you should first import the service in your module, like this:

import {NgxImageCompressService} from "ngx-image-compress";

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [NgxImageCompressService],
  bootstrap: [AppComponent],
})
export class AppModule {
}

Usage

Here how to use the service in your component.

Using upload and compress function, independently

This option is giving control over the compression process.

compressFile() signature is detailed here

import {Component} from "@angular/core";
import {NgxImageCompressService} from "ngx-image-compress";

@Component({
  selector: "app-root",
  template: `
      <button (click)="compressFile()">Upload and compress Image</button>
      <img [src]="imgResultBeforeCompression" *ngIf="imgResultBeforeCompression" />
      <img [src]="imgResultAfterCompression" *ngIf="imgResultAfterCompression"  />
  `,
})
export class AppComponent {

  constructor(private imageCompress: NgxImageCompressService) {
  }

  imgResultBeforeCompression: string = "";
  imgResultAfterCompression: string = "";

  compressFile() {
    this.imageCompress.uploadFile().then(
      ({image, orientation}) => {

        this.imgResultBeforeCompression = image;
        console.log("Size in bytes of the uploaded image was:", this.imageCompress.byteCount(image));

        this.imageCompress
          .compressFile(image, orientation, 50, 50) // 50% ratio, 50% quality
          .then(
            (compressedImage) => {
              this.imgResultAfterCompression = compressedImage;
              console.log("Size in bytes after compression is now:", this.imageCompress.byteCount(compressedImage));
            }
          );
      }
    );
  }
}

Performing a single upload, and compressing automatically to a given max size

Quicker method.

Getting directly an image at a maximum of "X" MegaBytes, using an optimised algorithm:

import {Component} from "@angular/core";
import {NgxImageCompressService} from "ngx-image-compress";

@Component({
  selector: "app-root",
  template: `
      <button (click)="compressFile()">Upload and compress Image</button>
      <img [src]="imgResult" *ngIf="imgResult" />
  `,
})
export class AppComponent {

  constructor(private imageCompress: NgxImageCompressService) {
  }

  imgResult: string = "";

  compressFile() {
    const MAX_MEGABYTE = 2;
    this.imageCompress
      .uploadAndGetImageWithMaxSize(MAX_MEGABYTE) // this function can provide debug information using (MAX_MEGABYTE,true) parameters
      .then(
        (result: string) => {
          this.imgResult = result;
        },
        (result: string) => {
          console.error('The compression algorithm didn\'t succed! The best size we can do is', this.imageCompress.byteCount(result), 'bytes')
          this.imgResult = result;
        });
  }
}

Multiple files support

For uploading multiple files, instead of using

this.imageCompress.uploadFile()
  .then((singleFile: { image: string, fileName:string, orientation: number }) => //...

You can use

this.imageCompress.uploadMultipleFiles()
  .then((arrayOfFiles: { image: string, fileName:string, orientation: number }[]) => //...

Behavior if no files have been selected

With uploadFile() and uploadMultipleFiles(), nothing will happen when the user is selecting nothing, close the file selection, and cancel the upload.

If you want the upload promise to reject in such case, please use: uploadFileOrReject() or uploadMultipleFilesOrReject() instead.

compressFile() signature

The signature of compressFile() is:

compressFile(image, orientation, ratio, quality, maxWidth, maxHeight)

Parameter Type Description
image string DataUrl (string) representing the image
orientation number EXIF Orientation value using the DOC_ORIENTATION enum value
ratio number Maximum scale factor as a percentage (optional, default: 50) 1
quality number JPEG quality factor as a percentage (optional, default: 50) 2
maxWidth number Maximum width in pixels if you need to resize (optional, default: 0 - no resize)
maxHeight number Maximum height in pixels if you need to resize (optional, default: 0 - no resize)

[1] Ratio: "50" will decrease the resolution of each dimension by 2, i.e.: image of 2000 X 1500 pixels will become 1000 X 750 pixels, while the whole resolution will be reduced by 4.

[2] Quality: For more info about this parameter, read this guide

How it works under the hood?

We will use Renderer2, and transform the image using HTML canvas encrustation. In fact you can use the static version in the library and import renderer by yourself, or remplace it with another DOM abstraction, using RendererFactory2.

There are mainly two advantage for using Renderer2 abstraction over direct DOM manipulation (by using ElementRef or window.document directly).

  • Angular keeps the component and the view in sync using templates, data binding, and change detection. All of them are bypassed when we update the DOM Directly.
  • DOM Manipulation works only in a browser. In the future we will not be able to use other platforms like web worker, in-server (for Server-Side Rendering), in a mobile or a desktop application, etc... where there is no browser.
  • The DOM APIs do not sanitize the data. Hence, it is possible to inject a script, thereby, opening our app to XSS injection attacks.

That's being said, please note that because of some iOS limitations/bugs when using Renderer2, we still are using window.document API, for the upload part only (not the canvas itself).

Change log

2022/05/10

  • Adding new API to reject promise if the user close the upload windows and no files are selected (uploadFileOrReject and uploadMultipleFileOrReject)
    New functions avoid any breaking change in existing code, no changes are necessary, you can still use uploadFile or uploadMultiple. With these, the promise stays silent when the user cancel the upload selection.
  • Adding the file name in the upload result

2022/02/22

  • Fix Exif rotation for new version of Chrome 79+
  • Native upload for Safari browser

2022/01/19

  • Implementing a built-in algorithm, looping several times, to reach a desired max size in Megabytes
  • Readme updates and docs in method signature directly

2022/01/04

  • Readme update
  • CI/CD with github action

2021/12/21

  • Update to Angular 13
  • Upload multiple file at once
  • Add support for resizing image size (compressFile() is now accepting maxWidth and maxHeight paramaters)
  • Cleanup types
  • Invalid image rejection
  • General refactoring

2021/11/14

  • Added support for max size

2020/11/18

  • Update to Angular 11
  • Fix upload for iOS
  • Expose getOrientation api publically

2019/07/01

  • Update to Angular 8 (angular 7 is enough)
  • Fix DOC_ORIENTATION import (not a required import)

2019/01/09

  • Since Angular 6 include its own packaging system, I no longer need my webpack config to build it.
  • Everything is working in angular 7 without complaint now (test app is on github)

2018/10/04

  • Adding Live example.
  • Everything is now working and tested but I will make some arrangement to the code in index.ts before submitting it again to npm, in order to make it more handy.

2017/12/06

  • Upload to Github
  • Need some fixes and tests to be use as a static library
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].