在基于EXIF的Chrome浏览器中,将照片从文件绘制到画布进行旋转



Chrome会根据其exif数据自动旋转绘制到画布的文件输入中的任何图像。这很好,但iOS不这么做。有没有办法防止这种行为,这样我就可以自己变换图像了。我写了一个修复程序,它在iOS中有效,禁用该修复程序在Android上有效。。。宁愿禁用/启用然后玩浏览器识别游戏。

我试着将图像的样式设置为图像方向:无。。。。但这并没有起到任何作用。仍然旋转。

编辑:我通过查看样式对象上的"imageOrientation"是未定义的还是新创建的img标记上的空字符串来检测到这一点。也许这不是一个完美的测试,但它适用于我测试的情况。不确定它有多经得起未来考验。

这应该是经得起未来考验的:

// returns a promise that resolves to true  if the browser automatically
// rotates images based on exif data and false otherwise
function browserAutoRotates () {
return new Promise((resolve, reject) => {
// load an image with exif rotation and see if the browser rotates it
const image = new Image();
image.onload = () => {
resolve(image.naturalWidth === 1);
};
image.onerror = reject;
// this jpeg is 2x1 with orientation=6 so it should rotate to 1x2
image.src = 'data:image/jpeg;base64,/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRcZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRAf/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';
});
}

真正确定浏览器是否基于exif数据旋转的唯一方法是:加载一个带有exif ratation的图像,看看结果如何。

这是由于Chrome 81中的一个更新,该更新现在具有并尊重"图像方向"属性。https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation

Chrome现在默认所有图像为"from image",这意味着它将读取EXIF数据来确定图像的旋转数据。以下基本上是我所做的检测浏览器是否支持这样的功能,因为iOS和其他浏览器的未来版本也希望这样做。

function browserImageRotationSupport(){
let imgTag = document.createElement('img');
return imgTag.style.imageOrientation !== undefined;
}

我能够使用这个测试来区分浏览器:

if (CSS.supports("image-orientation", "from-image")) {
...
}
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);

我使用这个片段来检查它是否是IOS,如果是IOS则只旋转画布ctx。我认为旧版本的android不会自动旋转图像,因为我仍然收到来自android用户的错误报告。

如果在作为DOM一部分的画布上绘制,则在canvas元素上设置CSS(而不是img(将解决此问题。

canvas {
image-orientation: none;
}

在编写时,元素必须在DOM中,因为它使用了计算样式。它只存在于DOM上下文中。你可以在Chromium跟踪器上阅读更多内容。

https://bugs.chromium.org/p/chromium/issues/detail?id=158753

最新更新