77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
export function getOrientation(arrayBuffer: ArrayBuffer): number {
|
|
try {
|
|
const view = new DataView(arrayBuffer);
|
|
|
|
if (view.getUint16(0, false) !== 0xFFD8) {
|
|
return 1;
|
|
}
|
|
|
|
let offset = 2;
|
|
const length = view.byteLength;
|
|
|
|
while (offset < length) {
|
|
if (view.getUint16(offset + 2, false) <= 8) return 1;
|
|
const marker = view.getUint16(offset, false);
|
|
offset += 2;
|
|
|
|
if (marker === 0xFFE1) {
|
|
const exifOffset = offset + 10;
|
|
if (exifOffset > length) return 1;
|
|
|
|
const little = view.getUint16(exifOffset, false) === 0x4949;
|
|
offset += 4 + view.getUint32(exifOffset + 4, little);
|
|
|
|
const tags = view.getUint16(offset, little);
|
|
offset += 2;
|
|
|
|
for (let i = 0; i < tags; i++) {
|
|
const tagOffset = offset + (i * 12);
|
|
if (view.getUint16(tagOffset, little) === 0x0112) {
|
|
return view.getUint16(tagOffset + 8, little);
|
|
}
|
|
}
|
|
} else if ((marker & 0xFF00) !== 0xFF00) {
|
|
break;
|
|
} else {
|
|
offset += view.getUint16(offset, false);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.warn("Could not read EXIF orientation, using default:", error);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
export function applyOrientation(
|
|
ctx: CanvasRenderingContext2D,
|
|
orientation: number,
|
|
width: number,
|
|
height: number,
|
|
) {
|
|
switch (orientation) {
|
|
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;
|
|
}
|
|
}
|