将文件中的照片绘制到 canvas 根据 EXIF 在 Chrome 中旋转
Drawing photo from file to canvas rotates in Chrome based on EXIF
Chrome 根据其 exif 数据将任何图像从绘制到 canvas 的文件输入自动旋转。这很好,但 iOS 却没有做到这一点。有没有办法防止这种行为,这样我就可以自己转换图像。通过我编写的修复程序,它可以在 iOS 中运行,禁用该修复程序可以在 Android 上运行...宁愿 disable/enable 然后玩浏览器识别游戏。
我试过将图像的样式设置为图像方向:none; ....但是那没有做任何事情。还是旋转一下。
编辑:我通过查看样式对象上的 'imageOrientation' 是否未定义或新创建的 img 标签上是否为空字符串来检测到这一点。也许不是一个完美的测试,但它适用于我测试的情况。不确定未来的证据如何。
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
我使用此代码段来检查它是否为 IOS,如果它为 IOS,则仅旋转 canvas ctx。我认为 android 的旧版本不会自动旋转图像,因为我仍然收到来自 android 用户的错误报告。
这是由于 Chrome 81 中的更新,现在具有并尊重 'image-orientation' 属性。 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;
}
在 canvas
元素上设置 CSS 而不是 img
将解决此问题=22=].
canvas {
image-orientation: none;
}
在编写时,元素必须在 DOM 中,因为它使用计算样式。这只存在于 DOM 上下文中。您可以在 Chromium 跟踪器上的问题中阅读更多内容。
https://bugs.chromium.org/p/chromium/issues/detail?id=158753
我能够使用此测试来区分浏览器:
if (CSS.supports("image-orientation", "from-image")) {
...
}
这应该是未来的证明:
// 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 比率的图像,然后查看结果如何。
Chrome 根据其 exif 数据将任何图像从绘制到 canvas 的文件输入自动旋转。这很好,但 iOS 却没有做到这一点。有没有办法防止这种行为,这样我就可以自己转换图像。通过我编写的修复程序,它可以在 iOS 中运行,禁用该修复程序可以在 Android 上运行...宁愿 disable/enable 然后玩浏览器识别游戏。
我试过将图像的样式设置为图像方向:none; ....但是那没有做任何事情。还是旋转一下。
编辑:我通过查看样式对象上的 'imageOrientation' 是否未定义或新创建的 img 标签上是否为空字符串来检测到这一点。也许不是一个完美的测试,但它适用于我测试的情况。不确定未来的证据如何。
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
我使用此代码段来检查它是否为 IOS,如果它为 IOS,则仅旋转 canvas ctx。我认为 android 的旧版本不会自动旋转图像,因为我仍然收到来自 android 用户的错误报告。
这是由于 Chrome 81 中的更新,现在具有并尊重 'image-orientation' 属性。 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;
}
在 canvas
元素上设置 CSS 而不是 img
将解决此问题=22=].
canvas {
image-orientation: none;
}
在编写时,元素必须在 DOM 中,因为它使用计算样式。这只存在于 DOM 上下文中。您可以在 Chromium 跟踪器上的问题中阅读更多内容。
https://bugs.chromium.org/p/chromium/issues/detail?id=158753
我能够使用此测试来区分浏览器:
if (CSS.supports("image-orientation", "from-image")) {
...
}
这应该是未来的证明:
// 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 比率的图像,然后查看结果如何。