Javascript: Reset image's orientation before uploading

Javascript: Reset image's orientation before uploading

·

2 min read

The images can have 8 orientation types like the image below and we have reset its orientation, I mean to convert to be like the first image.

all.png

First, I will get the current image's orientation

export async function getOrientation(file: File): Promise<number> {

  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (event: any) => {
      const view = new DataView(event.target.result);

      if (view.getUint16(0, false) !== 0xFFD8) {
        resolve(-2);
      }

      const length = view.byteLength;
      let offset = 2;

      while (offset < length) {
        const marker = view.getUint16(offset, false);
        offset += 2;

        if (marker === 0xFFE1) {
          if (view.getUint32(offset += 2, false) !== 0x45786966) {
            resolve(-1);
          }
          const little = view.getUint16(offset += 6, false) === 0x4949;
          offset += view.getUint32(offset + 4, little);
          const tags = view.getUint16(offset, little);
          offset += 2;

          for (let i = 0; i < tags; i++) {
            if (view.getUint16(offset + (i * 12), little) === 0x0112) {
              resolve(view.getUint16(offset + (i * 12) + 8, little));
            }
          }
        } else if ((marker && 0xFF00) !== 0xFF00) {
          // nothing to do
        }
        offset += view.getUint16(offset, false);
      }

      resolve(-1);
    };
    reader.onerror = (error) => {
         reject("Can not get the image orientation", error);
    };
    reader.readAsArrayBuffer(file.slice(0, 64 * 1024));
  });
}

Then reset its orientation by use this function:

export async function resetOrientation(file: File, srcOrientation: number) {
  return new Promise(async (resolve) => {
    const img = new Image();
    const reader = new FileReader();
    const orient = await getOrientation(file);

    reader.readAsDataURL(file);

    reader.onerror = () => {
        // console.log('reader error', e);
    };
    reader.onload = (e: any) => {
      const fileHandle = e.target.result;
        // orient = getOrientationClone(_base64ToArrayBuffer(fileHandle));
      img.src = fileHandle;
    };

    img.onload = () => {
      const width = img.width,
        height = img.height,
        canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

        // set proper canvas dimensions before transform & export
      if (4 < srcOrientation && srcOrientation < 9) {
        canvas.width = height;
        canvas.height = width;
      } else {
        canvas.width = width;
        canvas.height = height;
      }

        // transform context before drawing image
      switch (orient) {
      case 2: ctx.transform(-1, 0, 0, 1, width, 0); break;
      case 3: ctx.transform(-1, 0, 0, -1, width, height); break;
      case 4: ctx.transform(1, 0, 0, -1, 0, height); break;
      case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
      case 6: ctx.transform(0, 1, -1, 0, height , 0); break;
      case 7: ctx.transform(0, -1, -1, 0, height , width); break;
      case 8: ctx.transform(0, -1, 1, 0, 0, width); break;
      default: break;
      }

        // draw image
      ctx.drawImage(img, 0, 0);

        // export base64
      canvas.toBlob((imgBlob: any) => {
        imgBlob.name = file.name;
        resolve(imgBlob);
      });
    };

  });

}

Hope it's helpful for you!