2026-01-20 09:02:26 -06:00

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;
}
}