Skip to content

Instantly share code, notes, and snippets.

@Monomachus
Created March 10, 2020 10:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Monomachus/261c067206440f059f53a78c647d870c to your computer and use it in GitHub Desktop.
Save Monomachus/261c067206440f059f53a78c647d870c to your computer and use it in GitHub Desktop.
Using orientation to flip image in Ionic 4
onFileChosen(event: Event) {
const pickedFile = (event.target as HTMLInputElement).files[0];
if (!pickedFile) {
return;
}
let originalOrientation = 1;
ImageHelper.getOrientation(pickedFile, (orientation) => {
console.log('Orientation', orientation);
originalOrientation = orientation;
const fr = new FileReader();
fr.onload = () => {
const dataUrl = fr.result.toString();
this.manipulateImage(dataUrl, originalOrientation, pickedFile.name);
};
fr.readAsDataURL(pickedFile);
});
}
private manipulateImage(dataUrl: string, originalOrientation: number, imageName?: string) {
ImageHelper.resizeAndResetOrientation(dataUrl, originalOrientation, NEEDED_WIDTH, (fixedDataUrl) => {
this.selectedImage = fixedDataUrl;
const transformedFile = ImageHelper.dataURLtoFile(fixedDataUrl, ImageHelper.getImageName(imageName, 'some-random-file.jpg'));
this.imagePick.emit(transformedFile);
});
}
import { Observable, Observer } from 'rxjs';
export class ImageHelper {
public static getOrientation(file, callback) {
const reader = new FileReader();
reader.onload = (event) => {
const view = new DataView((event.target as any).result as ArrayBuffer);
if (view.getUint16(0, false) !== 0xFFD8) { return callback(-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) {
return callback(-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) {
return callback(view.getUint16(offset + (i * 12) + 8, little));
}
}
} else if ((marker & 0xFF00) !== 0xFF00) { break; } else { offset += view.getUint16(offset, false); }
}
return callback(-1);
};
reader.readAsArrayBuffer(file.slice(0, 64 * 1024));
}
public static getOrientationFromBase64(srcBase64, callback) {
const file = this.dataURLtoFile(srcBase64, 'some-random-name.jpg');
const reader = new FileReader();
reader.onload = (event) => {
const view = new DataView((event.target as any).result);
if (view.getUint16(0, false) !== 0xFFD8) { return callback(-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) {
return callback(-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) {
return callback(view.getUint16(offset + (i * 12) + 8, little));
}
}
} else if ((marker & 0xFF00) !== 0xFF00) { break; } else { offset += view.getUint16(offset, false); }
}
return callback(-1);
};
reader.readAsArrayBuffer(file.slice(0, 64 * 1024));
}
public static dataURLtoFile(dataurl, filename: string) {
const arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
public static resizeAndResetOrientation(srcBase64, srcOrientation, desiredWidth: number, callback) {
const img = new Image();
img.onload = () => {
let divideFactor = 1;
if (img.width > desiredWidth) {
divideFactor = desiredWidth / img.width;
}
const width = img.width * divideFactor,
height = img.height * divideFactor,
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 (srcOrientation) {
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, img.width * divideFactor, img.height * divideFactor);
// export base64
callback(canvas.toDataURL('image/jpeg'));
};
img.src = srcBase64;
}
public static getImageName(imageName: string, name: string) {
return !!imageName ? imageName : name;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment