How to Compress Image With Custom Ratio Without The Support of Third Party Library ?| Devstringx

Back to Blog
Image Compression using code only

How to Compress Image With Custom Ratio Without The Support of Third Party Library ?| Devstringx

Compress Images without the Support of Third Party Library

Let’s create a new angular project using the Angular CLI tool by executing the following CLI command

  • ng new image-compression
  • Would you like to add Angular routing? Yes
  • Which stylesheet format would you like to use? CSS

What’s Image Compression?

Image Compression is when we reduce the resolution of the actual image. Ex – suppose there is an image with a resolution of 1250 x 450 and for our logo we want the image to be compressed in 100 x 30 resolution then we have to reduce the height and width of the image with the required resolution (height and width) so that the UI won’t distort.

What’s Different Here?

In this blog we will not use any third-party library, this will be pure code. In third-party libraries, the image is compressed in their own format we cannot set the required height or width of the image also most of these libraries return base64 data and some APIs don’t accept base64 so in this blog, we will set the required resolution (height and width) of the image and after the compression of the image, the returned data will File not base64 so the API can accept it without any problem or we also can do many things with the file according to the requirement.

Create a Service for Image Compression

Now we’ll create a new service for Image compression to keep the code of image compression in one place so that we won’t have to write the code again and again. To generate the image compression service in the service folder, execute the following command

  • ng generate service services/image compression

This will create an ImageCompressionService inside the services folder.

Update the ImageCompressionService

Now, open the image-compression-service.ts file inside the services folder and make the following changes:

Import {Observable} from ‘rxjs’

We will create a separate method in the image-compression-service.ts file called compress () that will take file, maxHeight, and maxWidth that will return an observable of File type.

The method will look like this:

compress(file: File, maxHeight: number, maxWidth: number): Observable<File> {

}

Here, if we didn’t want to pass the height or width, we only want to reduce only one of the parameters then we simply can pass null so that the height or width will remain original.

Now, inside the compress () function write this code:

const imageType = file.type || 'image/jpeg'

const reader = new FileReader()

reader.readAsDataURL(file)

return Observable.create(observer => {

reader.onload = ev => {

const img = this.createImage(ev)

setTimeout(() => {

const canvas = document.createElement('canvas')

if (img.height < img.width) {

if (maxWidth) {

canvas.width = img.width > maxWidth ? maxWidth : img.width

} else {

canvas.width = img.width

}

if (maxHeight) {

canvas.height = img.height > maxHeight ? maxHeight : img.height

} else {

canvas.height = img.height

}

} else {

if (maxHeight) {

canvas.height = img.height > maxHeight ? maxHeight : img.height

} else {

canvas.height = img.height

}

if (maxWidth) {

canvas.width = canvas.height * 50 / 100

} else {

canvas.width = canvas.width

}

}

const canvasCtx = <CanvasRenderingContext2D>canvas.getContext('2d')

canvasCtx.drawImage(img, 0, 0, canvas.width, canvas.height)

canvasCtx.canvas.toBlob(

blob => {

observer.next(

new File([blob], file.name, {

type: imageType,

lastModified: Date.now(),

}),

)

},

imageType,

)

})

}

reader.onerror = error => observer.error(error)

})

Also Read:- Streaming YouTube Video in Angular Application

In this code, we are creating an instance/object of FileReader class and then reading the file as dataUrl using the reader.readAsDataUrl() method.

Now, we have to return the Observable of the file type but before this first create a method named createImage () that will create a new Image instance with the Image data.

private createImage(ev) {

const imageContent = ev.target.result

const img = new Image()

img.src = imageContent

return img

}

Your code will look like this. Now, using the createImage() function we will get an image with the actual image source, after that we will create a canvas using the document.createElement(‘canvas’) function. Now we will check if the actual image resolution (height or width) is less than the required resolution if yes then we will use the actual resolution of the image but if the actual resolution is greater than the required resolution then we will set the required resolution in the canvas.

and then we will create an instance canvasCtx using canvas.getContext(‘2d’) function and using that instance we will drawImage and then we will return it as BLOB like this –

Your Final Code Will Look Like this

image-compression.service.ts

import { Observable } from ‘rxjs’;

compress(file: File, maxHeight: number, maxWidth: number): Observable<File> {

const imageType = file.type || 'image/jpeg'

const reader = new FileReader()

reader.readAsDataURL(file)

return Observable.create(observer => {

reader.onload = ev => {

const img = this.createImage(ev)

setTimeout(() => {

const canvas = document.createElement('canvas')

if (img.height < img.width) {

if (maxWidth) {

canvas.width = img.width > maxWidth ? maxWidth : img.width

} else {

canvas.width = img.width

}

if (maxHeight) {

canvas.height = img.height > maxHeight ? maxHeight : img.height

} else {

canvas.height = img.height

}

} else {

if (maxHeight) {

canvas.height = img.height > maxHeight ? maxHeight : img.height

} else {

canvas.height = img.height

}

if (maxWidth) {

canvas.width = canvas.height * 50 / 100

} else {

canvas.width = canvas.width

}

}

const canvasCtx = <CanvasRenderingContext2D>canvas.getContext('2d')

canvasCtx.drawImage(img, 0, 0, canvas.width, canvas.height)

canvasCtx.canvas.toBlob(

blob => {

observer.next(

new File([blob], file.name, {

type: imageType,

lastModified: Date.now(),

}),

)

},

imageType,

)

})

}

reader.onerror = error => observer.error(error)

})

}

private createImage(ev) {

const imageContent = ev.target.result

const img = new Image()

img.src = imageContent

return img

}

Also Read:- Generating Excel File in Angular 9 using “ExcelJs” with Custom Font Family 

app.component.ts

import { take } from ‘rxjs/operators’;

constructor(

private imageCompressor: ImageCompressionService

) {}

getFile(event): void {

const file = event.target.files[0]

this.imageCompressor.compress(file, 100, 20).pipe(take(1)).subscribe(compressedImage => {

console.log(compressedImage)

}

}

app.component.html

<input type=”file” (change)=”getFile($event)” accept=”.jpg,.jpeg,.png” />

FAQs

  • How do I compress images in Angular?

To compress images in Angular, you can use an image compression library such as ng2-image-compress or ngx-image-compressor. These libraries provide directives or components that can be added to your Angular application to allow for easy image compression.

  • Is there a built-in image compression feature in Angular 2 or higher?

No, there is no built-in image compression feature in Angular 2 or higher. However, various third-party libraries can be used to add image compression functionality to your Angular application.

  • Can I use the Angular 2 image compression library in an Angular 1 application?

No, the Angular 2 image compression library is not compatible with Angular 1. If you are using Angular 1, you can use a different image compression library such as angular-image-compress.

  • How do I choose the best image compression library for my Angular application?

When choosing an image compression library for your Angular application, consider the following factors:

  • Compatibility with your version of Angular
  • Ease of use and integration into your application
  • Performance and efficiency of the compression algorithm
  • Any additional features or functionality provided by the library

It may be helpful to do some research and compare different options before making a decision.

  • Can I use the Angular image compression library to compress other types of files besides images?

Some image compression libraries, such as ng2-pdf-viewer, may also support the compression of PDF files. However, most libraries are specifically designed for compressing images and may not be suitable for other types of files.

To read more interesting angular development related articles and information from us here at Devstringx, then we have a lot to choose from for you.

Share this post

Back to Blog